You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Written after the 2026-09-01 release (dev → prod, merge 14422133, 60 commits). At time of writing dev and prod are identical and the production deploy is still pending.
This is a state-of-the-world list, not a plan. It supersedes the "what is left" section of #1299.
1 · Blocking production today
#1298 — production email delivery has been dead since 2026-06-18. Invalid RESEND_API_KEY. Signup and password reset are both broken, and checkout dies at the auth wall. This is an environment variable, not code — the 60-commit release changed nothing about it. This is the highest-value fix available and nothing else on this list competes with it.
2 · Stream ops rollout — unblocked, and order matters
The rollout was gated on the server-side join/end routes being live in production. They now are. Run in exactly this order:
Confirm POST /api/meetings/[meetingId]/join and POST /api/meetings/[meetingId]/end are serving production traffic.
npx tsx scripts/stream/backfill-call-member-role.ts --apply — must be first. The grants pre-flight currently reports 7 members across 4 calls that do not hold call_member. Revoking before backfilling locks those people out of their own calls.
Delete the ~10 mock calls from the Stream app. Note dev, preview and prod share one Stream app — a "test" deletion is a real deletion.
Email Stream support the two open questions from Stream: what the SDK offers that we have not assessed, with costs #1160: whether recording_external_storage also covers transcription output, and confirmation of the $6.00 / 1,000 call-minute HD recording rate (the public pricing page lists only the $1.50 audio figure; $6.00 comes from a blog post).
12 open Dependabot PRs (#1288–#1296, #411, #460, #736). #1293 is the Stream one: the recommendation on record is to close it, add a Dependabot ignore for stream-chat-reactmajor, and take the @stream-io/node-sdk 0.7.64 → 0.8.3 bump separately (it is a no-op beyond a Node ≥22.12 floor we already meet). Deliberate version holds are recorded in #1283.
4 · Parked by decision
Recordings → external storage. Blocked on the bucket-vendor choice. Do not retire the transfer pipeline or its workflow until it lands. The SDK is already capable — no version bump needed. Supabase is not viable for shipping: the org is on the free plan, whose 50 MB/object cap clamps the bucket's nominal 500 MB against real recordings of 450–900 MB.
Background blur (Stream: restore noise cancellation and background blur, and put a size budget on the server function #1158). The only honest verification is a real Netlify deploy against the non-raisable 250 MB Lambda cap, and the server function already sits at ~245 MB. Blur itself is unmetered and @stream-io/video-filters-web is already on disk; Krisp (@stream-io/audio-filters-web) is the paid, per-participant-minute half and is what failed the deploy 18 times out of 18.
Two-party browser session, >30 min. Still needs a human. Cannot use a deploy preview — BETTER_AUTH_TRUSTED_ORIGINS is the prod URL in every Netlify context, so preview sign-in 403s INVALID_ORIGIN. Needs a local dev server on node@22.
5 · Database
Production schema is fully current with dev as of this release — verified at 145/145 tables, 0 missing columns, 118/118 enums with no missing or stale labels (the SUPABASE → PLATFORM rename is fully applied), and both sidecar objects present (onboarding_draft_payload_size CHECK, consultant_review_legacy_pair_key partial unique index).
Two follow-ups fall out of that:
prisma db push cannot run against this database. Prisma's migrate engine fails P1017 through Supabase's session pooler, even though a plain pg client connects fine. Schema work currently needs either the Supabase API or the offline route: prisma migrate diff --from-empty --to-schema to generate expected DDL, then diff it against information_schema / pg_enum / pg_indexes with pg.
Two columns exist in the database but not in the schema, and a db push would drop both: ConsultantReview.isAnonymous (62/62 rows populated) and AppointmentFeedback.slotOfAppointmentId (3/4). Harmless while nothing pushes, but a db push --accept-data-loss in CI would take them silently. Someone should decide deliberately whether isAnonymous is dead.
6 · Quality and hygiene
dev's new_security_rating is now 1 (was 4) — all three typescript:S5852 criticals closed. new_reliability_rating is still 3 and fails the gate. Unrelated to this wave and not yet investigated.
No CI validation of .coderabbit.yaml. It was silently invalid for 168 commits (chore(review): fix .coderabbit.yaml so it actually loads #1309) because CodeRabbit fails closed into defaults and reports it only inside a collapsed <details> block. A schema-validation step on change would stop that recurring: npx ajv-cli validate -s schema.v2.json -d .coderabbit.yaml --spec=draft2020 --strict=false.
Zero documentation updates across the entire Stream train. Nine PRs merged without touching docs/stream/, against the standing preference for a docs pass alongside substantive change. Several files there still describe NextAuth and a streamCallId format not used in months.
Staff hold Stream's global admin role (lib/user.ts), which carries global read-channel — one stolen staff session reads every DM platform-wide, with no audit row. Stream subsystem — the tail #1134's PR train did not close #1144 separately proposes granting adminmore widely; reconcile before either moves.
MeetingSession.organizationId uses appointment funding while chat uses plan-then-appointment, so an org that delivers a self-funded session sees nothing in its Recordings tab. Fixing it widens org visibility — an ADR-20 amendment, not a bug fix.
Call duration is never measured.MeetingSession has no startedAt, and one call can have many sessions, which the one-row-per-call model cannot represent. The fix is to readvideo_query_call_stats (one row per session, with call_duration_seconds), not to build attendance tracking.
Written after the 2026-09-01 release (
dev→prod, merge14422133, 60 commits). At time of writingdevandprodare identical and the production deploy is still pending.This is a state-of-the-world list, not a plan. It supersedes the "what is left" section of #1299.
1 · Blocking production today
#1298 — production email delivery has been dead since 2026-06-18. Invalid
RESEND_API_KEY. Signup and password reset are both broken, and checkout dies at the auth wall. This is an environment variable, not code — the 60-commit release changed nothing about it. This is the highest-value fix available and nothing else on this list competes with it.2 · Stream ops rollout — unblocked, and order matters
The rollout was gated on the server-side join/end routes being live in production. They now are. Run in exactly this order:
POST /api/meetings/[meetingId]/joinandPOST /api/meetings/[meetingId]/endare serving production traffic.npx tsx scripts/stream/backfill-call-member-role.ts --apply— must be first. The grants pre-flight currently reports 7 members across 4 calls that do not holdcall_member. Revoking before backfilling locks those people out of their own calls.npx tsx scripts/stream/ensure-call-type-grants.ts --apply --routes-are-deployednpx tsx scripts/stream/ensure-app-settings.ts --applynpx tsx scripts/stream/ensure-webhook-subscription.ts --applyrecording_external_storagealso covers transcription output, and confirmation of the $6.00 / 1,000 call-minute HD recording rate (the public pricing page lists only the $1.50 audio figure; $6.00 comes from a blog post).3 · Open PRs
12 open Dependabot PRs (#1288–#1296, #411, #460, #736). #1293 is the Stream one: the recommendation on record is to close it, add a Dependabot
ignoreforstream-chat-reactmajor, and take the@stream-io/node-sdk0.7.64 → 0.8.3 bump separately (it is a no-op beyond a Node ≥22.12 floor we already meet). Deliberate version holds are recorded in #1283.4 · Parked by decision
@stream-io/video-filters-webis already on disk; Krisp (@stream-io/audio-filters-web) is the paid, per-participant-minute half and is what failed the deploy 18 times out of 18.BETTER_AUTH_TRUSTED_ORIGINSis the prod URL in every Netlify context, so preview sign-in 403sINVALID_ORIGIN. Needs a local dev server onnode@22.5 · Database
Production schema is fully current with
devas of this release — verified at 145/145 tables, 0 missing columns, 118/118 enums with no missing or stale labels (theSUPABASE→PLATFORMrename is fully applied), and both sidecar objects present (onboarding_draft_payload_sizeCHECK,consultant_review_legacy_pair_keypartial unique index).Two follow-ups fall out of that:
prisma db pushcannot run against this database. Prisma's migrate engine failsP1017through Supabase's session pooler, even though a plainpgclient connects fine. Schema work currently needs either the Supabase API or the offline route:prisma migrate diff --from-empty --to-schemato generate expected DDL, then diff it againstinformation_schema/pg_enum/pg_indexeswithpg.db pushwould drop both:ConsultantReview.isAnonymous(62/62 rows populated) andAppointmentFeedback.slotOfAppointmentId(3/4). Harmless while nothing pushes, but adb push --accept-data-lossin CI would take them silently. Someone should decide deliberately whetherisAnonymousis dead.6 · Quality and hygiene
dev'snew_security_ratingis now 1 (was 4) — all threetypescript:S5852criticals closed.new_reliability_ratingis still 3 and fails the gate. Unrelated to this wave and not yet investigated..coderabbit.yaml. It was silently invalid for 168 commits (chore(review): fix .coderabbit.yaml so it actually loads #1309) because CodeRabbit fails closed into defaults and reports it only inside a collapsed<details>block. A schema-validation step on change would stop that recurring:npx ajv-cli validate -s schema.v2.json -d .coderabbit.yaml --spec=draft2020 --strict=false.docs/stream/, against the standing preference for a docs pass alongside substantive change. Several files there still describe NextAuth and astreamCallIdformat not used in months.7 · Filed, not fixed
adminrole (lib/user.ts), which carries globalread-channel— one stolen staff session reads every DM platform-wide, with no audit row. Stream subsystem — the tail #1134's PR train did not close #1144 separately proposes grantingadminmore widely; reconcile before either moves.MeetingSession.organizationIduses appointment funding while chat uses plan-then-appointment, so an org that delivers a self-funded session sees nothing in its Recordings tab. Fixing it widens org visibility — an ADR-20 amendment, not a bug fix.MeetingSessionhas nostartedAt, and one call can have many sessions, which the one-row-per-call model cannot represent. The fix is to readvideo_query_call_stats(one row per session, withcall_duration_seconds), not to build attendance tracking.