feat: add six capabilities the registry was missing - #78
Merged
Conversation
Each of these fills a hole in the registry's own symmetry, found while backfilling supabase-flutter's compliance file against the full public API. storage.analytics.access_catalog file_buckets and vector_buckets both have an accessor capability (access_bucket, access_vector_index). Analytics has seventeen operations and no way to name the handle you need before any of them. auth.passkey.list_passkeys, update_passkey, delete_passkey auth.passkey_admin covers listing and deleting another user's passkeys, but there was nothing for a user managing their own, which is the more common flow. storage.file_buckets.request_cancellation, storage.configuration.auto_retry database and functions both have request_cancellation, and database has configuration.auto_retry. Storage is the one area with retry and abort behaviour but no id for either, even though aborting a large upload is more user-visible than aborting a query. client.lifecycle.dispose The client area had no lifecycle group, so releasing sockets, refresh timers and worker threads had nowhere to go. Garbage-collected runtimes with no deterministic teardown should declare this not_applicable.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe change adds capability declarations in three areas. Authentication now supports user-scoped passkey listing, metadata updates, and deletion. Client capabilities now document lifecycle configuration and deterministic resource disposal. Storage capabilities now include Iceberg catalog access, cancellation of in-flight requests, and automatic retry configuration. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Removes client.lifecycle.dispose, the lifecycle group, and the client area description change, following review feedback on #78. Leaves capabilities/client.yaml byte-identical to main. Two reasons. The id was not adjudicable: it needed an escape hatch so garbage-collected runtimes could declare not_applicable, but process termination releases resources on every runtime, so nothing observable separated "reclaims automatically" from "implemented". And the teardown surface a caller can see is already registered, via realtime.client.disconnect, realtime.client.remove_all_channels and realtime.channel.unsubscribe.
QuintinWillison
approved these changes
Aug 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds six capability ids across two areas, plus one new group.
These came out of backfilling supabase-flutter's
sdk-compliance.yamlagainst its full public API (supabase-flutter#1673). Reaching 100% coverage meant every public symbol needed a home, which made it obvious which operations the registry has no id for. Each one below is a gap in the registry's own symmetry rather than a Dart-shaped request: in every case a sibling area already has the equivalent capability.storage.analytics.access_catalogstorage.file_buckets.access_bucket("Scope subsequent file operations to a specific bucket") andstorage.vector_buckets.access_vector_index("Scope subsequent vector operations to a specific index within a bucket") both exist.Analytics has seventeen operations across namespaces and tables, and no id for the handle you need before you can call any of them. Worth noting the asymmetry is recent: #74 and #76 filled in the analytics operations without adding the accessor the other two groups have.
auth.passkey.list_passkeys,update_passkey,delete_passkeyauth.passkey_admin.list_passkeysandauth.passkey_admin.delete_passkeyalready cover an admin enumerating and revoking a user's passkeys. There was nothing for a user managing their own credentials, which is the more common flow of the two, and no id at all for renaming one.update_passkeyis described narrowly (mutable metadata, such as the friendly name) since the credential itself is immutable.storage.file_buckets.request_cancellationandstorage.configuration.auto_retrydatabase.using_modifiers.request_cancellationandfunctions.invocation.request_cancellationboth exist, as doesdatabase.configuration.auto_retry.Storage was the one area with retry and abort behaviour and no id for either, which is arguably backwards: aborting a multi-megabyte upload is more user-visible than aborting a query.
auto_retryneeds a newconfigurationgroup in the storage area, matching the group of the same name in database.What I deliberately left out
Four gaps surfaced in the same audit that I do not think belong here:
Supabase.instance.dispose). This started out in the PR asclient.lifecycle.disposeand has been dropped following review. Two reasons. First, the id was not adjudicable: it needed an escape hatch so garbage-collected runtimes could declarenot_applicable, but process termination releases resources on every runtime, so there was no observable test separating "reclaims automatically" from "implemented". Second, the teardown surface a caller can actually see is already registered, viarealtime.client.disconnect,realtime.client.remove_all_channelsandrealtime.channel.unsubscribe. A whole-clientdisposeis largely the aggregate of those plus internal timers and connection pooling, so its presence or absence says little about parity that the existing ids do not already say. Releasing resources idiomatically is a baseline every SDK owes its framework rather than a feature it can lack.Supabase.initialize,instance,isInitialized). Every SDK has it, but it is the precondition for the whole matrix rather than a feature within it.SupabaseQueryBuilder.stream). This one is a genuine inconsistency, but possibly on the Dart side. The registry already carries the modifiers of this capability, since supabase-flutter registersSupabaseStreamFilterBuilder.equnderdatabase.using_filters.eqandSupabaseStreamBuilder.orderunderdatabase.using_modifiers.order, yet there is no id for the operation those modify. supabase-js has no direct equivalent (you compose a channel with postgres changes by hand), so this may be Dart sugar that should be attributed differently rather than a missing id. Raising it as a question rather than proposing an id.withConverter). The Dart idiom for what TypeScript does with generics, so not a cross-SDK capability.Compliance impact
None of these is breaking. No id is renamed and no existing entry changes, so every SDK's
sdk-compliance.yamlkeeps validating; the six new ids simply default tonot_implementeduntil an SDK declares them.supabase-flutter implements all six and will declare them in a follow-up, which moves the corresponding symbols out of its generic top-level
supporting_symbolslist into the features they actually belong to. Its disposal symbols stay insupporting_symbols, which is where they already are today.Test plan
npm run validate:OK — capability matrix is valid.npm test: 195 passed across 14 files.npm run typecheck: clean.capabilities/*.yamlthat none of the six ids already exists under another name, and that the newstorage.configurationgroup is new.capabilities/client.yamlis byte-identical tomainafter dropping the disposal id.