Skip to main content

SP3.5 Cloud Realtime — manual two-identity cross-device checklist (2026-07-20)

Headless tests cannot attach a SECOND identity's JWT with a publishable key (same limitation documented across packages/client_sdk/test/cloud/*_live_test.dart), so true cross-device visibility — the whole point of SP3.5 — is proven manually. The automated proofs cover everything else: the fake-port adapter path (test/cached_realtime_test.dart), the end-to-end Beat 2 path (test/cloud/realtime_beat2_test.dart), and the single-identity live wire (test/cloud/realtime_live_test.dart).

Preconditions

  • Migration 20260720000100_realtime_publication.sql applied live to bgedvvmihygwxhjxlvfu (the five watched tables published + REPLICA IDENTITY FULL).
  • Two sessions signed in to the SAME household: a parent (device A) and a child member (device B) — two devices, or two app instances / profiles.
  • Device B's CHILD member MUST have consent_state = 'granted' — an unconsented or pendingConsent child is frozen by RLS (see M4 consent-freeze behavior below) and will correctly receive NO events beyond its own status row. Do not mistake that expected freeze for a realtime failure.
  • Supply a unique SMOKE_RUN_ID per run to avoid fixture row collisions (households/members are not torn down between runs; only the WS channel is disposed). Example: SMOKE_RUN_ID=manual_$(date +%s).

Beat 2 (the headline)

  1. Device B (child): submit a chore that needs approval; leave the app open on the child's Today/companion surface.
  2. Device A (parent): approve the child's submission.
  3. Expect on device B, with NO manual refresh: the approval flips to approved and the Beat 2 celebration fires; the wallet balance increases by the granted tokens within a couple of seconds.

Roster / chores live

  1. Device A: add a new member and create a chore.
  2. Expect on device B: the roster and chore list update live.

Isolation (dual gate holds on the wire)

  1. Sign a THIRD identity into a DIFFERENT household on a third session.
  2. Repeat steps 1–5. Expect: the third session sees NONE of household 1's events — RLS scopes the realtime delivery, not just the REST reads. Note: The RLS-on-the-wire guarantee (postgres_changes reuses the same RLS SELECT policies incl. the consent freeze) was proven at the SQL level in the companion RLS review (.superpowers/sdd/task-11-report.md) and by the append-only/parent-write-denied probes. This manual step confirms it end-to-end over a live socket; it is not first-discovery.

Teardown

  1. Sign out on device B. Expect: no further events arrive (the channel is torn down via Client.dispose() on the data-mode/auth transition).