feat: add seven capabilities the registry was missing - #78
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 |
| group: observability | ||
| - id: client.lifecycle.dispose | ||
| name: Client Disposal | ||
| description: Deterministically release every resource the client holds, including websocket connections, background refresh timers, worker threads and pooled HTTP connections, so a client can be torn down without leaking them. Runtimes that reclaim these automatically have no equivalent. |
There was a problem hiding this comment.
I'm find this difficult to parse and vision how it applies to any given SDK's framework or runtime. I think the sentence on the end is the most confusing piece, as interpretation depends on where in any given stack you're looking at this from... ultimately a process terminating is available on every runtime, and that definitely disposes of all resources at that point! 🤷 ... I'm assuming this has come from a specific concern in Flutter/Dart, however ultimately I think any SDK that's idiomatically following framework conventions should intrinsically be managing disposal/release properly. That is, any SDK should be doing this as a foundational 'basic', surely?
Adds seven capability ids across three areas, plus two new groups.
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.client.lifecycle.disposeThe client area had four groups and none of them covered lifecycle, so releasing websocket connections, background refresh timers, worker threads and pooled HTTP connections had nowhere to go.
The description is written so that runtimes without deterministic teardown can declare it
not_applicablerather thannot_implemented, since in a garbage-collected environment with no disposal protocol there is nothing to implement. That is the same treatmentfunctions.invocation.timeoutalready gets in the Dart compliance file.What I deliberately left out
Three more gaps surfaced in the same audit that I do not think belong here:
Supabase.initialize,instance,isInitialized). Every SDK has it, but it is the precondition for the whole matrix rather than a feature within it. Disposal is different: it is a real capability an SDK can lack.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 seven new ids simply default tonot_implementeduntil an SDK declares them.supabase-flutter implements all seven and will declare them in a follow-up, which moves 21 symbols out of its generic top-level
supporting_symbolslist into the features they actually belong to.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 seven ids already exists under another name, and that both new groups (storage.configuration,client.lifecycle) are new.