From 698264c59dbc5c9f9b80ac7bfb6f1082cde2271a Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Fri, 28 Aug 2026 06:11:24 -0300 Subject: [PATCH 1/2] feat(realtime): add postgres_changes_wait capability Registers the wait-for-server-confirmation option on postgres_changes subscriptions (see supabase-js#2630) so SDKs can declare compliance against a stable feature ID. --- .../capabilities/realtime.yaml | 4 +++ .../subscriptions/postgres_changes_wait.md | 25 +++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 packages/capability-matrix/specs/realtime/subscriptions/postgres_changes_wait.md diff --git a/packages/capability-matrix/capabilities/realtime.yaml b/packages/capability-matrix/capabilities/realtime.yaml index 3bfb30f..e608ff6 100644 --- a/packages/capability-matrix/capabilities/realtime.yaml +++ b/packages/capability-matrix/capabilities/realtime.yaml @@ -98,6 +98,10 @@ features: name: Multiple Postgres Changes Row Filters description: Apply more than one PostgREST-style filter expression to a single Postgres changes subscription, combined with AND, to receive events only for rows matching all of them. group: subscriptions + - id: realtime.subscriptions.postgres_changes_wait + name: Wait for Postgres Changes Confirmation + description: Delay reporting the subscription as active until the server confirms the postgres_changes subscription is actually streaming, avoiding a race where changes are missed if the channel joins before replication catches up, via the postgres_changes_options.wait channel option (with a configurable timeout). + group: subscriptions - id: realtime.subscriptions.private_channel name: Private Channel (RLS) description: Mark a channel as private to enforce Row Level Security on Postgres change events and restrict broadcast and presence access to authorized users. diff --git a/packages/capability-matrix/specs/realtime/subscriptions/postgres_changes_wait.md b/packages/capability-matrix/specs/realtime/subscriptions/postgres_changes_wait.md new file mode 100644 index 0000000..1ff6115 --- /dev/null +++ b/packages/capability-matrix/specs/realtime/subscriptions/postgres_changes_wait.md @@ -0,0 +1,25 @@ +# Wait for Postgres Changes Confirmation + +## Behavior + +By default, a channel is reported as successfully subscribed as soon as it joins the topic on the server, before the server has necessarily started streaming Postgres change events for that subscription. This creates a race: if replication for the subscription isn't active yet when the client starts treating the channel as ready, changes emitted in that gap can be missed. + +Setting `postgres_changes_options.wait` to `true` on the channel config defers reporting a successful subscription until the server sends an explicit confirmation that the postgres_changes subscription is active and streaming. `postgres_changes_options.timeout` controls how long to wait for that confirmation, in milliseconds (default `15000`). + +## Prerequisites + +Only meaningful on a channel with a `postgres_changes` binding; has no effect on channels without one. Requires a Realtime server version that sends the subscription-active confirmation message. + +## Errors + +- subscription not confirmed — the server responds with `wait` enabled but the subscription cannot be confirmed active (e.g. replication setup failure); the subscribe outcome carries the server's reason instead of a false success +- timeout — the server does not confirm within `postgres_changes_options.timeout` milliseconds + +## Notes + +- Without `wait: true`, a successful subscription is reported on channel join regardless of postgres_changes streaming state — the existing default behavior is unchanged for callers who don't opt in. + +## Related + +- [Subscribe to Postgres Changes](realtime.subscriptions.postgres_changes) — the underlying subscription this option confirms +- [Subscribe](realtime.channel.subscribe) — the join call whose success is delayed by this option From 1b0489b94c002971ffb0e31fcc1ef0d8a0fb4832 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Fri, 28 Aug 2026 20:24:27 -0300 Subject: [PATCH 2/2] docs(capability-matrix): drop the spec Notes section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A dedicated Notes section is redundant on a document that is already free-form notes — fold platform/behavior asides into Behavior or Prerequisites instead. Updates the template, the capability-matrix skill's guidance, and the postgres_changes_wait spec. Addresses review feedback on #106. --- .claude/skills/capability-matrix/SKILL.md | 10 ++++++---- packages/capability-matrix/specs/TEMPLATE.md | 9 +++------ .../realtime/subscriptions/postgres_changes_wait.md | 6 +----- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/.claude/skills/capability-matrix/SKILL.md b/.claude/skills/capability-matrix/SKILL.md index 2fcacfd..05a776d 100644 --- a/.claude/skills/capability-matrix/SKILL.md +++ b/.claude/skills/capability-matrix/SKILL.md @@ -100,10 +100,12 @@ There is no schema field for "this only applies to mobile/web SDKs" — that nuance (biometric auth, secure enclave storage, browser-only APIs like `localStorage`) is expected to live in prose, not structured data. If a feature's behavior is inherently platform-scoped, suggest a line either in -the feature's `description` or, if it has a spec, in the spec's `## Notes` -section. Point out *why* it matters: SDKs that don't apply can declare -`not_applicable` in their `sdk-compliance.yaml`, but only if the constraint -is documented somewhere a maintainer would see it. +the feature's `description` or, if it has a spec, folded into the spec's +`## Behavior` (or `## Prerequisites`, if it gates the feature) — specs don't +have a separate `## Notes` section, since the whole document is already +notes-in-nature. Point out *why* it matters: SDKs that don't apply can +declare `not_applicable` in their `sdk-compliance.yaml`, but only if the +constraint is documented somewhere a maintainer would see it. ## Presenting findings diff --git a/packages/capability-matrix/specs/TEMPLATE.md b/packages/capability-matrix/specs/TEMPLATE.md index 3cd5525..1a8646e 100644 --- a/packages/capability-matrix/specs/TEMPLATE.md +++ b/packages/capability-matrix/specs/TEMPLATE.md @@ -19,7 +19,9 @@ Spec: [https://github.com/supabase/auth/blob/master/openapi.yaml](https://github + Do not include language-specific function signatures; implementations vary across SDKs. + Fold in platform quirks, security considerations, rate limits, and deprecation warnings + where they're relevant, rather than collecting them in a separate section. --> ## Prerequisites @@ -32,11 +34,6 @@ Spec: [https://github.com/supabase/auth/blob/master/openapi.yaml](https://github - `error_code` — description of when this error is returned -## Notes - - - ## Related diff --git a/packages/capability-matrix/specs/realtime/subscriptions/postgres_changes_wait.md b/packages/capability-matrix/specs/realtime/subscriptions/postgres_changes_wait.md index 1ff6115..56b6c22 100644 --- a/packages/capability-matrix/specs/realtime/subscriptions/postgres_changes_wait.md +++ b/packages/capability-matrix/specs/realtime/subscriptions/postgres_changes_wait.md @@ -4,7 +4,7 @@ By default, a channel is reported as successfully subscribed as soon as it joins the topic on the server, before the server has necessarily started streaming Postgres change events for that subscription. This creates a race: if replication for the subscription isn't active yet when the client starts treating the channel as ready, changes emitted in that gap can be missed. -Setting `postgres_changes_options.wait` to `true` on the channel config defers reporting a successful subscription until the server sends an explicit confirmation that the postgres_changes subscription is active and streaming. `postgres_changes_options.timeout` controls how long to wait for that confirmation, in milliseconds (default `15000`). +Setting `postgres_changes_options.wait` to `true` on the channel config defers reporting a successful subscription until the server sends an explicit confirmation that the postgres_changes subscription is active and streaming. `postgres_changes_options.timeout` controls how long to wait for that confirmation, in milliseconds (default `15000`). Without `wait: true`, a successful subscription is reported on channel join regardless of postgres_changes streaming state — the default behavior is unchanged for callers who don't opt in. ## Prerequisites @@ -15,10 +15,6 @@ Only meaningful on a channel with a `postgres_changes` binding; has no effect on - subscription not confirmed — the server responds with `wait` enabled but the subscription cannot be confirmed active (e.g. replication setup failure); the subscribe outcome carries the server's reason instead of a false success - timeout — the server does not confirm within `postgres_changes_options.timeout` milliseconds -## Notes - -- Without `wait: true`, a successful subscription is reported on channel join regardless of postgres_changes streaming state — the existing default behavior is unchanged for callers who don't opt in. - ## Related - [Subscribe to Postgres Changes](realtime.subscriptions.postgres_changes) — the underlying subscription this option confirms