release: dev → prod — 2026-08-14 (Stream operator-script correctness + consent decision) - #1156
Conversation
…#1134) (#1153) Applied against the live app and it was refused: UpdateApp failed: invalid event types for hook 44a1d716-…: event types [message.flagged user.flagged] do not belong to product 'video' Stream partitions event types by product and a hook may only carry its own. The app has exactly one hook, scoped to `video`. The two chat-moderation events can never live on it. The script had no concept of `product`, so it reported all five unsubscribed events as plainly "missing" — which reads as one write away from fixed. Two of them were impossible. Worse, `updateAppSettings` rejects the whole payload atomically, so the single impossible event cost the three achievable ones in the same write and nothing landed at all. Now each hook is offered only what its product permits, and any handled event with no hook to carry it is reported as a configuration gap rather than a pending write. The script does not create the missing hook: that decides a public URL and starts real deliveries, so it belongs to a human in the dashboard, exactly as the existing "no webhook at all" branch already does. Verified against production. The video hook went 6 -> 9 events, so call.session_participant_joined / _left and call.session_started now deliver and MeetingAttendance can finally be written. Chat moderation stays dead until a 'chat' hook exists — which the script now says out loud instead of implying it is one run away. Part of #1134
… (#1154) A decline made after recording has started stops it and discards what was captured. Decided rather than deferred because it was blocking the rest of the consent work in #1146. The reasoning is that withdrawing consent means the recording of that person should not exist, and a shorter recording is still that recording. It is also the only answer consistent with what shipped in #1139: the one-to-one notice tells people declining is real and costs them nothing, and quietly keeping a partial would make that sentence untrue after the fact. The cost is recorded rather than glossed. A consultant can lose a whole session's recording to a decline in its final minutes, so the pre-join copy has to say plainly that a decline can arrive at any point — and the discard has to be a real delete reaching Stream's stored asset and any in-flight transfer, not a status flag. Nothing shipped is wrong today; enforcement is start-time only and the source says so. This records a decision to build, not a defect to repair. Part of #1134
✅ Deploy Preview for familiarise ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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 |
|




Two commits, both consequences of running last night's release against production rather than reasoning about it.
Part of #1134. No database change —
prisma migrate diff --from-config-datasourcereports no difference.The one that matters operationally
#1153 — the webhook subscription script could never have done its job.
Running it against production refused outright:
Stream partitions event types by product, and a hook may only carry events from its own. This app has exactly one hook, scoped to
video, so the two chat-moderation events could never live on it — no matter how many times the script ran.The script shipped in #1141 had no concept of
product. Its dry run reported all five unsubscribed events as plainly "missing", which reads as one write away from fixed. And becauseupdateAppSettingsrejects atomically, the two impossible events cost the three achievable ones in the same write, so nothing landed at all. Anyone running it would have seen the same five reported forever and reasonably concluded the write had simply not been run.It now offers each hook only what its product permits, and reports anything left over as a configuration gap rather than a pending write.
Already applied to production by hand. The video hook went from 6 to 9 events, so
call.session_participant_joined,call.session_participant_leftandcall.session_startednow deliver — which meansMeetingAttendancecan be written for the first time. That table has been at zero rows, which is whydetect-consultant-no-showshas been running daily against nothing.This release gets the corrected script into prod so the next person to run it is not misled by the old one.
The other
#1154 records the mid-session recording-decline decision: a decline made after recording has started stops it and discards what was captured. Documentation only. It unblocks the remaining consent work in #1146, and states the cost plainly — a consultant can lose a whole session's recording to a late decline, so the pre-join copy must say a decline can arrive at any time, and the discard has to be a real delete reaching Stream's stored asset and any in-flight transfer.
Operator action still outstanding
user.flaggedandmessage.flaggedneed a second webhook in the Stream dashboard, scoped to productchat, pointing athttps://familiarisenow.com/api/stream/webhooks. The script deliberately does not create it — that decides a public URL and starts live deliveries, which belongs to a human. Until it exists, chat moderation stays dead: every report the chat UI has ever written has landed in a queue nothing feeds.Not in this release
The video-quality work is not here. #1143 was closed after failing to deploy 18 times out of 18, and its fixes were reconstructed as #1155 without the 44 MB paid noise-cancellation package that was breaking the deploy. That ships separately once its own deploy is confirmed.