- Slack + email push companion to digest.gating_changed โ closes the named rev-90 next-sprint candidateRev 90 fired the gating change as an outbound webhook event + activity-log entry; rev 91 closes the named rev-90 next-sprint candidate by adding the matching Slack push (workspace-wide audit-trail channel via the workspace's slackWebhookUrl โ every admin sees the gating change in chat alongside the rev-90 audit log + outbound) and per-recipient email companion (the affected operator's own receipt of their gating change with subject 'Your digest delivery resumed' or 'Your digest is now muted'). Distinct surfaces: outbound webhook = downstream integrations (CRM, FinOps tool, audit), Slack = workspace-wide audit, email = per-recipient personal receipt. Best-effort everywhere; never blocks the prefs save (matches the rev-90 dispatch + activity-log discipline). New `buildDigestGatingChangedSlackPayload()` Slack block carries traffic-light or no-bell emoji depending on the new gating outcome plus mute reasons (weekend mute / quiet-hours window) inline. **Strategic significance**: closes the rev-90 named candidate. The full digest gating axis now reaches every operator-loaded channel โ outbound (rev 90 โ integrations), activity log (rev 90 โ audit), Slack (rev 91 โ workspace chat), email (rev 91 โ per-recipient inbox).
- In-dashboard gating outcome pill on every owner/admin member rowCloses the in-app visibility gap on the rev-89 multi-recipient gating primitive. Until rev 91 the rev-89 dashboard pill on the integrations panel showed the workspace-wide rollup ('Would send N of M') but admins couldn't see *who specifically* was muted without opening the rev-89 v1 endpoint. Rev 91 surfaces the per-recipient gating outcome inline on every owner/admin row in the workspace members panel โ `โ digest` (brand-green) or `๐ muted` (amber) with a tooltip explaining the mute reason (weekend mute / quiet-hours window / both). Pure derived state via the new `getDigestGatingForOwnerAdmins()` helper โ no schema, one extra workspace + members query that runs alongside the existing dashboard fetch. **Strategic significance**: pairs with the rev-89 integrations-panel rollup pill as the per-recipient detail surface. Matches the rev-89 colour vocabulary (brand-green when clean, amber when muted) so the two gating surfaces read with one consistent visual story.
- OpenAPI 3.1 spec rev-91 changelog blockDocuments the rev-91 multi-channel push surface in the OpenAPI 3.1 changelog header. The rev-89 multi-recipient gating endpoint + rev-90 digest-config endpoint were already typed in lockstep with their dashboard primitives; rev 91 adds no new v1 endpoints since the Slack + email channels are dispatched alongside (not downstream of) the existing `digest.gating_changed` outbound event. The protocol surface is unchanged; the multi-channel push completes the rev-90 closure-receipt loop on the operator-visible side. **Strategic significance**: keeps the cadence pattern alive โ every rev's OpenAPI changelog entry documents what happened on the typed-contract surface even when the protocol surface itself is stable. MCP-host code generators reading the spec see exactly when each rev's primitive landed.
- Visual polish โ gating pill colour vocabulary alignmentNew `.ld-member-gating-pill` CSS uses the same brand-green-vs-amber palette as the rev-89 `.ld-digest-gating-pill` so the two gating surfaces (integrations panel rollup + members panel per-row) read as siblings with one consistent visual story. 1px hover lift + 160ms transition for tactile click affordance + `cursor: help` so admins know to hover for the tooltip. Cumulative micro-polish (every rev 22+ has carried at least one). **Strategic significance**: keeps the rev-by-rev visual-hierarchy discipline alive โ the dashboard now has two related but distinct gating surfaces (workspace-wide rollup, per-member detail) wearing the same colour vocabulary so admins pattern-match instead of re-reading from scratch.