@open-everywhere/provider-slack 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/agent/app-manifest.ts +85 -8
  2. package/agent/channels/slack-events.ts +25 -0
  3. package/agent/channels/slack-front.ts +275 -2
  4. package/agent/channels/slack-home.ts +546 -0
  5. package/agent/channels/slack-memory-canvas.ts +382 -0
  6. package/agent/channels/slack-offboarding.ts +89 -0
  7. package/agent/channels/slack-origin-codec.ts +8 -0
  8. package/agent/channels/slack-side-panel.ts +104 -0
  9. package/agent/channels/slack-step-label.ts +177 -0
  10. package/agent/channels/slack.ts +29 -16
  11. package/agent/docs-generated.ts +1 -1
  12. package/agent/ops.ts +8 -0
  13. package/agent/provider-events.ts +1 -1
  14. package/agent/register.ts +15 -0
  15. package/agent/setup/page.ts +3 -1
  16. package/agent/slack-as-you.ts +107 -0
  17. package/agent/surface-parity.ts +3 -0
  18. package/dist/agent/app-manifest.d.ts +23 -0
  19. package/dist/agent/app-manifest.d.ts.map +1 -1
  20. package/dist/agent/app-manifest.js +64 -8
  21. package/dist/agent/app-manifest.js.map +1 -1
  22. package/dist/agent/channels/slack-events.d.ts +17 -0
  23. package/dist/agent/channels/slack-events.d.ts.map +1 -1
  24. package/dist/agent/channels/slack-events.js +16 -0
  25. package/dist/agent/channels/slack-events.js.map +1 -1
  26. package/dist/agent/channels/slack-front.d.ts +66 -1
  27. package/dist/agent/channels/slack-front.d.ts.map +1 -1
  28. package/dist/agent/channels/slack-front.js +188 -3
  29. package/dist/agent/channels/slack-front.js.map +1 -1
  30. package/dist/agent/channels/slack-home.d.ts +103 -0
  31. package/dist/agent/channels/slack-home.d.ts.map +1 -0
  32. package/dist/agent/channels/slack-home.js +473 -0
  33. package/dist/agent/channels/slack-home.js.map +1 -0
  34. package/dist/agent/channels/slack-memory-canvas.d.ts +65 -0
  35. package/dist/agent/channels/slack-memory-canvas.d.ts.map +1 -0
  36. package/dist/agent/channels/slack-memory-canvas.js +325 -0
  37. package/dist/agent/channels/slack-memory-canvas.js.map +1 -0
  38. package/dist/agent/channels/slack-offboarding.d.ts +31 -0
  39. package/dist/agent/channels/slack-offboarding.d.ts.map +1 -0
  40. package/dist/agent/channels/slack-offboarding.js +75 -0
  41. package/dist/agent/channels/slack-offboarding.js.map +1 -0
  42. package/dist/agent/channels/slack-origin-codec.d.ts.map +1 -1
  43. package/dist/agent/channels/slack-origin-codec.js +8 -0
  44. package/dist/agent/channels/slack-origin-codec.js.map +1 -1
  45. package/dist/agent/channels/slack-side-panel.d.ts +41 -0
  46. package/dist/agent/channels/slack-side-panel.d.ts.map +1 -0
  47. package/dist/agent/channels/slack-side-panel.js +78 -0
  48. package/dist/agent/channels/slack-side-panel.js.map +1 -0
  49. package/dist/agent/channels/slack-step-label.d.ts +17 -0
  50. package/dist/agent/channels/slack-step-label.d.ts.map +1 -0
  51. package/dist/agent/channels/slack-step-label.js +170 -0
  52. package/dist/agent/channels/slack-step-label.js.map +1 -0
  53. package/dist/agent/channels/slack.d.ts.map +1 -1
  54. package/dist/agent/channels/slack.js +29 -16
  55. package/dist/agent/channels/slack.js.map +1 -1
  56. package/dist/agent/docs-generated.js +1 -1
  57. package/dist/agent/docs-generated.js.map +1 -1
  58. package/dist/agent/ops.d.ts.map +1 -1
  59. package/dist/agent/ops.js +7 -1
  60. package/dist/agent/ops.js.map +1 -1
  61. package/dist/agent/provider-events.js +1 -1
  62. package/dist/agent/provider-events.js.map +1 -1
  63. package/dist/agent/register.d.ts.map +1 -1
  64. package/dist/agent/register.js +14 -1
  65. package/dist/agent/register.js.map +1 -1
  66. package/dist/agent/setup/page.d.ts.map +1 -1
  67. package/dist/agent/setup/page.js +3 -1
  68. package/dist/agent/setup/page.js.map +1 -1
  69. package/dist/agent/slack-as-you.d.ts +38 -0
  70. package/dist/agent/slack-as-you.d.ts.map +1 -0
  71. package/dist/agent/slack-as-you.js +82 -0
  72. package/dist/agent/slack-as-you.js.map +1 -0
  73. package/dist/agent/surface-parity.d.ts.map +1 -1
  74. package/dist/agent/surface-parity.js +3 -0
  75. package/dist/agent/surface-parity.js.map +1 -1
  76. package/package.json +33 -3
@@ -1,6 +1,9 @@
1
+ import { type SlackUserDeactivation } from "./slack-offboarding.js";
2
+ import type { OffboardOutcome } from "@open-everywhere/core/agent/adapter-api.js";
1
3
  import { type Channel, type RouteHandlerArgs } from "eve/channels";
2
4
  import { liveSupervisorDeps, type SlackEventEnvelope } from "./slack-events.js";
3
- import { EventDedupe, ThreadFifo, type SingleWindowMentionPolicy, type DmSeat, type SetKeyViewResult } from "@open-everywhere/core/agent/adapter-api.js";
5
+ import { EventDedupe, ThreadFifo, type SingleWindowMentionPolicy, type DmSeat, type SetKeyViewResult, type PersonOptOutState } from "@open-everywhere/core/agent/adapter-api.js";
6
+ import { type ParsedHomeClick, type ParsedHomeOpen, type ParsedHomeSubmission } from "./slack-home.js";
4
7
  import { type ParsedSlackShortcut } from "./slack-shortcut.js";
5
8
  /** An HTTP route handler — `RouteHandler` isn't a public eve export, so we mirror its shape. */
6
9
  type RouteHandler = (req: Request, args: RouteHandlerArgs) => Promise<Response>;
@@ -22,6 +25,13 @@ export type FrontDecision = {
22
25
  readonly kind: "join";
23
26
  readonly reason: string;
24
27
  readonly env: SlackEventEnvelope;
28
+ }
29
+ /** OPE-2423 — a `user_change` event. Ours: a `deleted` user is a deactivation report for core's
30
+ * offboarding lever (slack-offboarding.ts); every other profile edit is acked with no work. */
31
+ | {
32
+ readonly kind: "user-change";
33
+ readonly reason: string;
34
+ readonly env: SlackEventEnvelope;
25
35
  } | {
26
36
  readonly kind: "reaction";
27
37
  readonly reason: string;
@@ -91,6 +101,37 @@ export type FrontDecision = {
91
101
  readonly kind: "shortcut";
92
102
  readonly reason: string;
93
103
  readonly shortcut: ParsedSlackShortcut;
104
+ }
105
+ /** A `channel_shared` (the channel became Slack Connect shared) — ours: re-run the memory canvas gate
106
+ * on that channel, which clears the app's canvas when the channel no longer passes (OPE-2451). */
107
+ | {
108
+ readonly kind: "channel-shared";
109
+ readonly reason: string;
110
+ readonly env: SlackEventEnvelope;
111
+ }
112
+ /** An `app_home_opened` for the HOME tab (OPE-2451) — ours: publish the person's own page. */
113
+ | {
114
+ readonly kind: "home-open";
115
+ readonly reason: string;
116
+ readonly open: ParsedHomeOpen;
117
+ }
118
+ /** An `oe_home:` click on the Home tab (OPE-2451) — ours: run a button, or open an item's modal. */
119
+ | {
120
+ readonly kind: "home-click";
121
+ readonly reason: string;
122
+ readonly click: ParsedHomeClick;
123
+ }
124
+ /** A submission of the Home tab's own modal (OPE-2451) — ours: run the action, republish the page. */
125
+ | {
126
+ readonly kind: "home-submit";
127
+ readonly reason: string;
128
+ readonly submission: ParsedHomeSubmission;
129
+ }
130
+ /** An `app_context_changed` (OPE-2457) — ours, and nothing to do. The subscription exists only so
131
+ * Slack attaches the viewed room to each side-panel `message.im`; the change itself wakes nothing. */
132
+ | {
133
+ readonly kind: "context-change";
134
+ readonly reason: string;
94
135
  };
95
136
  /**
96
137
  * Decide how the front route handles a raw inbound body. FORWARD is the fail-safe default:
@@ -180,10 +221,27 @@ export interface FrontOptions {
180
221
  * re-verifies standing host-side, then mints an ephemeral OAuth URL / opens the api-key intake.
181
222
  * Injectable for tests. */
182
223
  readonly handleConnectClick?: (payload: unknown) => Promise<boolean>;
224
+ /** OPE-2423 — hand one deactivation report to core's offboarding lever. Defaults to
225
+ * {@link routeSlackUserDeactivation} with a live `users.info` re-read. Injectable for tests. */
226
+ readonly routeUserDeactivation?: (d: SlackUserDeactivation) => Promise<OffboardOutcome>;
183
227
  /** Injected in tests; the live default is core's `handleGrantCardClick`. The signed grant-click
184
228
  * branch schedules it through the route's `waitUntil`, so this handler may outlive the empty
185
229
  * Slack acknowledgement. */
186
230
  readonly handleGrantCardClick?: (payload: unknown) => Promise<boolean>;
231
+ /** The three Home-tab handlers (OPE-2451). Injected in tests; the live defaults are slack-home.ts's,
232
+ * over the live Slack deps. Each runs after the empty acknowledgement, through `waitUntil`. */
233
+ readonly handleHomeOpened?: (open: ParsedHomeOpen) => Promise<boolean>;
234
+ readonly handleHomeClick?: (click: ParsedHomeClick) => Promise<boolean>;
235
+ readonly handleHomeSubmission?: (submission: ParsedHomeSubmission) => Promise<boolean>;
236
+ /** The domain memory canvas recheck a trust event runs (OPE-2451): a person joined the channel, or it
237
+ * was shared. Injected in tests; the live default is slack-memory-canvas.ts's, over the live deps. */
238
+ readonly recheckChannelCanvas?: (input: {
239
+ org: string;
240
+ teamId: string;
241
+ channelId: string;
242
+ trigger: "member-joined" | "channel-shared";
243
+ joinedUserId?: string;
244
+ }) => Promise<unknown>;
187
245
  /** SINGLE-WINDOW mention policy for one (channel, surface) — should the unified window own an
188
246
  * @mention here (suppress the native forward + keep the sibling as an addressed wake)?
189
247
  * Defaults to the live {@link slackSingleWindowMentionPolicy} (grain + fail-closed
@@ -238,6 +296,13 @@ export interface FrontOptions {
238
296
  * governance DM-delivery arm. Defaults to the live call; FAIL-CLOSED: undefined ⇒ the shortcut
239
297
  * wakes nothing and says so, never a wake in a guessed room. Injectable for tests. */
240
298
  readonly openDirectMessageChannel?: (userId: string) => Promise<string | undefined>;
299
+ /** The person opt-out read (OPE-2436): may the agent act on this person's content? Defaults to
300
+ * core's `readPersonOptOut`, which is fail-CLOSED (an unreadable store reads as opted out).
301
+ * Injectable for tests. */
302
+ readonly personOptOutFor?: (org: string, principalId: string) => Promise<PersonOptOutState>;
303
+ /** Tell one person, privately in their own DM, why a shortcut they pressed did nothing (OPE-2436).
304
+ * Best-effort. Defaults to `conversations.open` + `chat.postMessage`. Injectable for tests. */
305
+ readonly postPrivateNotice?: (userId: string, text: string) => Promise<void>;
241
306
  /** The trigger author's two membership facts, from ONE `users.info` probe — the exact pair every
242
307
  * wake route in slack-events.ts resolves. Two readers: the native `app_mention` forward's
243
308
  * external-policy gate, which calls it only when that policy is not inert (so a deployment on the
@@ -1 +1 @@
1
- {"version":3,"file":"slack-front.d.ts","sourceRoot":"","sources":["../../../agent/channels/slack-front.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"slack-front.d.ts","sourceRoot":"","sources":["../../../agent/channels/slack-front.ts"],"names":[],"mappings":"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"}
@@ -38,6 +38,7 @@
38
38
  // urlencoded body (Eve's own `eve_input:` HITL clicks, view_submission, slash
39
39
  // commands) still forwards exactly as before.
40
40
  // 4. Idempotency + per-thread FIFO guard the wake (see EventDedupe / ThreadFifo below).
41
+ import { parseSlackUserDeactivation, routeSlackUserDeactivation } from "./slack-offboarding.js";
41
42
  import { POST } from "eve/channels";
42
43
  import { SLACK_SIGNATURE_HEADER, SLACK_TIMESTAMP_HEADER, slackSignature, slackSignatureMatches } from "./slack-signature.js";
43
44
  import { slackSigningSecret } from "../setup/credentials.js";
@@ -45,10 +46,13 @@ import { slackContinuationToken } from "eve/channels/slack";
45
46
  import { callSlackWebApi } from "./slack-web-api.js";
46
47
  import { auditDmBotAuthorDrop, auditDmDriverAdmitted, dmDoorAdmitsDriver, parseMessageEvent, routeMessageEvent, liveDeps, routeNameDropEvent, liveNameDropDeps, parseChannelJoinEvent, routeChannelJoinEvent, liveChannelJoinDeps, parseSlackReactionEvent, routeReactionEvent, liveReactionDeps, routeSupervisorEvent, liveSupervisorDeps, supervisorFifoKey, bindableFor, bindableForJoin, bindableForReaction, slackSingleWindowMentionPolicy, slackDomainUsesUnifiedWindow, slackFrontTenantFenceDeclined, slackInteractivityTenantFenceDeclined, } from "./slack-events.js";
47
48
  import { slackInteractivityTenantIds } from "./slack-tenant-fence.js";
48
- import { EventDedupe, ThreadFifo, getOrCreateDmSeat as liveGetOrCreateDmSeat, touchDmSeat as liveTouchDmSeat, resolvePartition, domainKeyOf, isThreadEngaged, divertInboundToUnifiedWindow, isPrunedDeploymentWakeError, markUndeliveredAfterHeal, isUndeliveredAfterHeal, healPrunedDeploymentStrand, mintWakeId, slackVendorEventTime, spreadVendorTs, resolveWakeTrust, ambientSupervisorEnabled, getConfig, getOperationalStore, OE_APPROVAL_PREFIX, handleApprovalPayload as liveHandleApprovalPayload, OE_SETKEY_ACTION_PREFIX, OE_SETKEY_MODAL_CALLBACK, handleSetKeyClick as liveHandleSetKeyClick, handleSetKeyViewSubmission as liveHandleSetKeyViewSubmission, OE_CONNECT_ACTION_PREFIX, handleConnectClick as liveHandleConnectClick, OE_GRANT_ACTION_PREFIX, handleGrantCardClick as liveHandleGrantCardClick, buildRecord, enqueue as enqueueLogRecord, flushLogShip, stampNonMemberChatAuth, externalPolicyIsInert, recordWakeTail, tailAuthorGrain, dmWindowRegistryKey, stampSurfaceEventVerified, } from "@open-everywhere/core/agent/adapter-api.js";
49
- import { renderWakeMessage, slackChannelFactsFor, slackAuthorIsMember, slackClickerIsGuest, slackWakeAuthorFacts, slackExternalPolicyForRoom, applySlackExternalPolicy, stripUnfencedSlackAttachments, slackEnterpriseIdFromEnvelope, _resetAuthorMemberCache, } from "./slack-events.js";
49
+ import { EventDedupe, ThreadFifo, getOrCreateDmSeat as liveGetOrCreateDmSeat, touchDmSeat as liveTouchDmSeat, resolvePartition, domainKeyOf, isThreadEngaged, divertInboundToUnifiedWindow, isPrunedDeploymentWakeError, markUndeliveredAfterHeal, isUndeliveredAfterHeal, healPrunedDeploymentStrand, mintWakeId, slackVendorEventTime, spreadVendorTs, resolveWakeTrust, ambientSupervisorEnabled, getConfig, getOperationalStore, OE_APPROVAL_PREFIX, handleApprovalPayload as liveHandleApprovalPayload, OE_SETKEY_ACTION_PREFIX, OE_SETKEY_MODAL_CALLBACK, handleSetKeyClick as liveHandleSetKeyClick, handleSetKeyViewSubmission as liveHandleSetKeyViewSubmission, OE_CONNECT_ACTION_PREFIX, handleConnectClick as liveHandleConnectClick, OE_GRANT_ACTION_PREFIX, handleGrantCardClick as liveHandleGrantCardClick, buildRecord, enqueue as enqueueLogRecord, flushLogShip, stampNonMemberChatAuth, externalPolicyIsInert, recordWakeTail, tailAuthorGrain, dmWindowRegistryKey, stampSurfaceEventVerified, readPersonOptOut, auditPersonOptOutRefusal, PERSON_OPT_OUT_SHORTCUT_NOTICE, PERSON_OPT_OUT_UNREADABLE_NOTICE, } from "@open-everywhere/core/agent/adapter-api.js";
50
+ import { sidePanelViewedRoom, slackDmSystemNote } from "./slack-side-panel.js";
51
+ import { renderWakeMessage, slackChannelFactsFor, slackAuthorIsMember, slackClickerIsGuest, slackWakeAuthorFacts, slackExternalPolicyForRoom, applySlackExternalPolicy, stripUnfencedSlackAttachments, slackEnterpriseIdFromEnvelope, slackForm, _resetAuthorMemberCache, } from "./slack-events.js";
50
52
  import { buildSlackAuth, withForwardedSlackEnvelope } from "./slack-identity.js";
51
53
  import { holdRouteWork, routeHoldQuiesced, withSlackRouteHold } from "./slack-route-hold.js";
54
+ import { liveMemoryCanvasDeps, recheckChannelCanvas } from "./slack-memory-canvas.js";
55
+ import { handleHomeClick, handleHomeOpened, handleHomeSubmission, liveSlackHomeDeps, parseHomeClick, parseHomeOpened, parseHomeSubmission, } from "./slack-home.js";
52
56
  import { persistSlackAttachment, registerSlackAttachment } from "./slack-attachments.js";
53
57
  import { parseSlackShortcutPayload, shortcutMessageEvent, shortcutWakeKey, } from "./slack-shortcut.js";
54
58
  /** The public URL Slack POSTs every subscribed event to (Event Subscriptions Request URL). */
@@ -213,6 +217,17 @@ export function classifyEnvelope(rawBody, contentType) {
213
217
  if (grantClick !== undefined) {
214
218
  return { kind: "grant-click", reason: "block_actions oe_grant: click — ours, never forwarded", payload: grantClick };
215
219
  }
220
+ // THE HOME TAB (OPE-2451). Its clicks carry an `oe_home:` action id and its one modal a callback
221
+ // id of its own, so neither can be mistaken for another door's payload, nor for eve's.
222
+ const homePayload = decodeInteractivityPayload(rawBody);
223
+ const homeClick = parseHomeClick(homePayload);
224
+ if (homeClick !== undefined) {
225
+ return { kind: "home-click", reason: `block_actions oe_home: ${homeClick.action} — ours, never forwarded`, click: homeClick };
226
+ }
227
+ const homeSubmission = parseHomeSubmission(homePayload);
228
+ if (homeSubmission !== undefined) {
229
+ return { kind: "home-submit", reason: `view_submission for the Home tab modal (${homeSubmission.action}) — ours, never forwarded`, submission: homeSubmission };
230
+ }
216
231
  // A SHORTCUT (OPE-1376) — a `message_action` or `shortcut` payload. Ours, never forwarded; see
217
232
  // the `shortcut` arm of FrontDecision for why a forward could not do anything with it. It is
218
233
  // matched LAST among the urlencoded branches and cannot race any of them: every branch above
@@ -246,6 +261,28 @@ export function classifyEnvelope(rawBody, contentType) {
246
261
  if (eventType === "member_joined_channel") {
247
262
  return { kind: "join", reason: "member_joined_channel — channel-join intro candidate", env };
248
263
  }
264
+ if (eventType === "channel_shared") {
265
+ return { kind: "channel-shared", reason: "channel_shared — recheck the domain memory canvas", env };
266
+ }
267
+ if (eventType === "app_home_opened") {
268
+ // Only the HOME tab is ours (OPE-2451). The same event fires for the Messages tab, which has no
269
+ // page to publish, so that one forwards — eve acknowledges an event it has no handler for.
270
+ const open = parseHomeOpened(env);
271
+ if (open)
272
+ return { kind: "home-open", reason: "app_home_opened (home tab) — publish the person's page", open };
273
+ return { kind: "forward", reason: "app_home_opened for a tab other than home — nothing to publish" };
274
+ }
275
+ if (eventType === "app_context_changed") {
276
+ // THE SIDE PANEL (OPE-2457). Slack fires this each time the person moves the panel to another
277
+ // room. The room that matters arrives on the `message.im` they then send (`app_context`), so a
278
+ // change alone wakes nothing — but it is acknowledged HERE rather than forwarded, because a
279
+ // forward costs eve a parse and a re-verify for every click the person makes in Slack.
280
+ return { kind: "context-change", reason: "app_context_changed — the room rides the next side-panel message; nothing to wake" };
281
+ }
282
+ if (eventType === "user_change") {
283
+ // OPE-2423: slackChannel drops it, and a DEACTIVATED user is ours — automatic offboarding.
284
+ return { kind: "user-change", reason: "user_change — a deactivation report candidate", env };
285
+ }
249
286
  if (eventType === "reaction_added" || eventType === "reaction_removed") {
250
287
  // Inbound reactions: slackChannel drops them (no handler), so they're ours to ingest
251
288
  // (reaction-ingest.ts — a feedback signal on the bot's own replies + volume telemetry).
@@ -704,11 +741,23 @@ export function buildFrontHandler(innerHandler, opts = {}) {
704
741
  const handleSetKeyClick = opts.handleSetKeyClick ?? liveHandleSetKeyClick;
705
742
  const handleSetKeyViewSubmission = opts.handleSetKeyViewSubmission ?? liveHandleSetKeyViewSubmission;
706
743
  const handleConnectClick = opts.handleConnectClick ?? liveHandleConnectClick;
744
+ const routeUserDeactivation = opts.routeUserDeactivation ?? ((d) => routeSlackUserDeactivation(d, { usersInfo: (userId) => slackForm("users.info", `user=${encodeURIComponent(userId)}`) }));
707
745
  const handleGrantCardClick = opts.handleGrantCardClick ?? liveHandleGrantCardClick;
746
+ const homeOpened = opts.handleHomeOpened ?? ((open) => handleHomeOpened(open, liveSlackHomeDeps()));
747
+ const homeClicked = opts.handleHomeClick ?? ((click) => handleHomeClick(click, liveSlackHomeDeps()));
748
+ const recheckCanvas = opts.recheckChannelCanvas ?? ((input) => recheckChannelCanvas(input, liveMemoryCanvasDeps()));
749
+ const homeSubmitted = opts.handleHomeSubmission ?? ((submission) => handleHomeSubmission(submission, liveSlackHomeDeps()));
708
750
  const ambientEnabledFor = opts.ambientEnabledFor ?? ((surfaceKey) => ambientSupervisorEnabled(surfaceKey, getConfig().loadDomains()));
709
751
  const seatedSurface = opts.seatedSurfaceFor ?? slackDomainUsesUnifiedWindow;
710
752
  const mentionPolicyFor = opts.mentionPolicyFor ?? slackSingleWindowMentionPolicy;
711
753
  const openDirectMessageChannel = opts.openDirectMessageChannel ?? liveOpenDirectMessageChannel;
754
+ const personOptOutFor = opts.personOptOutFor ?? readPersonOptOut;
755
+ const postPrivateNotice = opts.postPrivateNotice ??
756
+ (async (userId, text) => {
757
+ const dm = await openDirectMessageChannel(userId);
758
+ if (dm)
759
+ await slackForm("chat.postMessage", new URLSearchParams({ channel: dm, text }).toString());
760
+ });
712
761
  const resolveDmSeat = opts.resolveDmSeat ?? ((org, dm, atIso) => liveGetOrCreateDmSeat(org, dm, atIso));
713
762
  const touchDmSeatFn = opts.touchDmSeatFn ?? liveTouchDmSeat;
714
763
  const dmPartnerTrustFor = opts.dmPartnerTrustFor ?? liveDmPartnerTrust;
@@ -1180,9 +1229,25 @@ export function buildFrontHandler(innerHandler, opts = {}) {
1180
1229
  // by design (the seat is one long-lived session over the whole DM, so replaying history a live
1181
1230
  // session already holds would duplicate it) — the tail is exactly the case that reasoning does
1182
1231
  // not cover, because a rotation is when the session stops holding it.
1232
+ // THE SIDE PANEL (OPE-2457) AND THE PERSON OPT-OUT (OPE-2436) — two host facts for a 1:1 DM, in
1233
+ // one trusted note. The viewed room passes every strictest-default gate first
1234
+ // (slack-side-panel.ts); the opt-out tells the seat not to promise memory the write road will
1235
+ // refuse anyway. A group DM states neither: it has no single person, and no panel.
1236
+ const systemNote = isGroup
1237
+ ? undefined
1238
+ : slackDmSystemNote({
1239
+ viewedRoom: await sidePanelViewedRoom({
1240
+ room: ev.appContext,
1241
+ teamId: ev.teamId,
1242
+ partnerTrust,
1243
+ channelInternal: async (id) => (await channelFactsFor(id)).internal === true,
1244
+ }),
1245
+ personOptOut: ev.userId ? await personOptOutFor(p.org, ev.userId) : undefined,
1246
+ });
1183
1247
  const message = renderWakeMessage(ev, () => atIso, {
1184
1248
  dm: true,
1185
1249
  trust: wakeTrust,
1250
+ ...(systemNote === undefined ? {} : { systemNote }),
1186
1251
  // The FENCE BACKSTOP for the whole DM family (OPE-1486) — the SAME refutation the taint stamp
1187
1252
  // and the policy gate read, so the three cannot disagree about one author. On a 1:1 it is a
1188
1253
  // no-op in practice (a refuted partner is already `unauth`, and `unauth` is already fenced);
@@ -1499,6 +1564,26 @@ export function buildFrontHandler(innerHandler, opts = {}) {
1499
1564
  // message twice on purpose, and only Slack's redelivery of ONE click is a duplicate.
1500
1565
  if (!(await notYetSeenKey(shortcutWakeKey(sc), sev)))
1501
1566
  return new Response(null, { status: 200 });
1567
+ // 🔴 THE PERSON OPT-OUT (OPE-2436). A message shortcut hands the agent somebody's message to act
1568
+ // on — summarise it, answer it, file it. When the message's AUTHOR opted out of agent actions on
1569
+ // their content and somebody ELSE pressed the button, nothing wakes: one refusal row, and a
1570
+ // private line to the person who pressed it. The author's own shortcut on their own message is
1571
+ // their own request, so it wakes as before. The read is fail-closed (core `readPersonOptOut`).
1572
+ const shortcutAuthor = sc.kind === "message" ? sc.message?.userId : undefined;
1573
+ if (shortcutAuthor && shortcutAuthor !== sc.userId) {
1574
+ const p = resolvePartition(bindableFor(sev));
1575
+ const authorOptOut = await personOptOutFor(p.org, shortcutAuthor);
1576
+ if (authorOptOut.optedOut) {
1577
+ console.log(`[open-everywhere:slack-front] message shortcut "${sc.callbackId}" in ${shortcutChannelId}: refused — the message's author opted out`);
1578
+ args.waitUntil(Promise.allSettled([
1579
+ auditPersonOptOutRefusal({ org: p.org, platform: p.platform, workspace: p.workspace, surface: p.surface, principalKey: shortcutAuthor }, "message-shortcut", { requestedBy: sc.userId, storeReadable: authorOptOut.readable }),
1580
+ // An unreadable store is the fail-closed GUESS, never the author's decision, so the presser
1581
+ // is not told the author asked for anything.
1582
+ postPrivateNotice(sc.userId, authorOptOut.readable ? PERSON_OPT_OUT_SHORTCUT_NOTICE : PERSON_OPT_OUT_UNREADABLE_NOTICE),
1583
+ ]));
1584
+ return new Response(null, { status: 200 });
1585
+ }
1586
+ }
1502
1587
  // BOTH halves of the attachment registry, seeded ONLY on a click that reaches a DISPATCHER —
1503
1588
  // the in-memory one for this process's seat, the durable one for a delegated worker in
1504
1589
  // another. (A dispatcher can still refuse further down, as `routeSupervisorEvent`'s own
@@ -1742,6 +1827,32 @@ export function buildFrontHandler(innerHandler, opts = {}) {
1742
1827
  }));
1743
1828
  return new Response(null, { status: 200 });
1744
1829
  }
1830
+ if (decision.kind === "home-open" || decision.kind === "home-click" || decision.kind === "home-submit") {
1831
+ // THE HOME TAB (OPE-2451). THE TENANT FENCE FIRST (OPE-1680), for the reason the approval branch
1832
+ // states: the page reads and changes a person's memory, keyed to a bare per-workspace member id,
1833
+ // so an unadmitted workspace reaching it is a foreign tenant reading our store.
1834
+ const ids = decision.kind === "home-open" ? decision.open : decision.kind === "home-click" ? decision.click : decision.submission;
1835
+ const fenceIds = {
1836
+ ...(ids.teamId === undefined ? {} : { teamId: ids.teamId }),
1837
+ ...(ids.enterpriseId === undefined ? {} : { enterpriseId: ids.enterpriseId }),
1838
+ userId: ids.userId,
1839
+ };
1840
+ if (slackInteractivityTenantFenceDeclined(fenceIds, decision.kind, decision.kind === "home-open" ? "front-home-event-branch" : "front-interactivity-branch")) {
1841
+ return fencedAck(new Response(null, { status: 200 }));
1842
+ }
1843
+ // ACK FIRST, WORK AFTER. Building the page reads memory and asks Slack who the person is and
1844
+ // which channels they sit in, which can cross Slack's three-second budget. An empty 200 also
1845
+ // CLOSES a submitted modal, which is what the person expects after Save or Forget; the page
1846
+ // they return to is republished with a one-line notice saying what happened.
1847
+ const run = decision.kind === "home-open" ? homeOpened(decision.open) : decision.kind === "home-click" ? homeClicked(decision.click) : homeSubmitted(decision.submission);
1848
+ args.waitUntil(run
1849
+ .then((handled) => {
1850
+ if (!handled)
1851
+ console.log(`[open-everywhere:slack-front] ${decision.kind} for ${ids.userId} did not complete`);
1852
+ })
1853
+ .catch(() => console.warn(`[open-everywhere:slack-front] ${decision.kind} failed after acknowledgement`)));
1854
+ return new Response(null, { status: 200 });
1855
+ }
1745
1856
  if (decision.kind === "setkey-submit") {
1746
1857
  // THE TENANT FENCE (OPE-1680), above the handler — this is the branch that WRITES A SECRET into
1747
1858
  // this deployment's store, keyed to the intake the payload names. A `view_submission` carries
@@ -1763,6 +1874,34 @@ export function buildFrontHandler(innerHandler, opts = {}) {
1763
1874
  }
1764
1875
  return forwardNative();
1765
1876
  }
1877
+ if (decision.kind === "channel-shared") {
1878
+ // THE CHANNEL WAS SHARED (OPE-2451): re-run the memory canvas gate at once, which clears the app's
1879
+ // own canvas there. The canvas reads the room verdict fresh, so the wake path's cached "internal"
1880
+ // cannot carry a pre-share answer into this decision.
1881
+ const ev = decision.env.event;
1882
+ const channelId = typeof ev?.channel === "string" ? ev.channel : undefined;
1883
+ const teamId = typeof decision.env.team_id === "string" ? decision.env.team_id : undefined;
1884
+ if (!channelId || !teamId)
1885
+ return OK();
1886
+ const sharedEnterpriseId = slackEnterpriseIdFromEnvelope(decision.env);
1887
+ if (slackInteractivityTenantFenceDeclined({ teamId, ...(sharedEnterpriseId === undefined ? {} : { enterpriseId: sharedEnterpriseId }), channelId }, "channel-shared", "front-channel-shared-branch")) {
1888
+ return fencedAck(OK());
1889
+ }
1890
+ let sharedOrg;
1891
+ try {
1892
+ sharedOrg = resolvePartition({
1893
+ channel: { kind: "slack" },
1894
+ session: { auth: { current: { attributes: { team_id: teamId, channel_id: channelId }, principalId: "", principalType: "slack-user" } } },
1895
+ }).org;
1896
+ }
1897
+ catch {
1898
+ sharedOrg = undefined;
1899
+ }
1900
+ if (sharedOrg !== undefined) {
1901
+ args.waitUntil(recheckCanvas({ org: sharedOrg, teamId, channelId, trigger: "channel-shared" }).catch(() => console.warn("[open-everywhere:slack-front] memory canvas recheck after a share failed")));
1902
+ }
1903
+ return OK();
1904
+ }
1766
1905
  if (decision.kind === "join") {
1767
1906
  // Channel-join intro. Only the BOT's own join is an invitation — a human joining a
1768
1907
  // channel we're in fires the same event and must be dropped. Fail-CLOSED here, the
@@ -1773,8 +1912,30 @@ export function buildFrontHandler(innerHandler, opts = {}) {
1773
1912
  if (!jev)
1774
1913
  return OK();
1775
1914
  const { userId: joinBotUserId } = await getBotIdentity();
1776
- if (!joinBotUserId || jev.userId !== joinBotUserId)
1915
+ if (!joinBotUserId || jev.userId !== joinBotUserId) {
1916
+ // A PERSON JOINED (OPE-2451). No intro, but the domain memory canvas re-runs its gate: the
1917
+ // newcomer may be a guest, and a canvas written before they joined would show them every line
1918
+ // of the domain's memory. The recheck can only CLEAR the app's own canvas, never write memory,
1919
+ // so an unresolved bot identity rechecks too. Fenced like every other door: a foreign tenant
1920
+ // never reaches this deployment's Slack calls.
1921
+ if (jev.teamId === undefined)
1922
+ return OK();
1923
+ if (slackInteractivityTenantFenceDeclined({ teamId: jev.teamId, ...(jev.enterpriseId === undefined ? {} : { enterpriseId: jev.enterpriseId }), channelId: jev.channelId, userId: jev.userId }, "member-joined", "front-join-branch")) {
1924
+ return fencedAck(OK());
1925
+ }
1926
+ let joinOrg;
1927
+ try {
1928
+ joinOrg = resolvePartition(bindableForJoin(jev)).org;
1929
+ }
1930
+ catch {
1931
+ joinOrg = undefined;
1932
+ }
1933
+ if (joinOrg !== undefined) {
1934
+ const teamId = jev.teamId;
1935
+ args.waitUntil(recheckCanvas({ org: joinOrg, teamId, channelId: jev.channelId, trigger: "member-joined", joinedUserId: jev.userId }).catch(() => console.warn("[open-everywhere:slack-front] memory canvas recheck after a join failed")));
1936
+ }
1777
1937
  return OK();
1938
+ }
1778
1939
  // Same two-layer idempotency as the message wake: Slack retries a slow ack, and a
1779
1940
  // double intro is exactly the annoyance the durable half exists to prevent.
1780
1941
  const joinKey = wakeKey(decision.env, jev.channelId, jev.ts);
@@ -1795,6 +1956,30 @@ export function buildFrontHandler(innerHandler, opts = {}) {
1795
1956
  args.waitUntil(routeChannelJoinEvent(jev, liveChannelJoinDeps(joinSend)).then(logOutcome("channel-join", jev.channelId, jev.ts)));
1796
1957
  return OK();
1797
1958
  }
1959
+ if (decision.kind === "context-change")
1960
+ return OK();
1961
+ if (decision.kind === "user-change") {
1962
+ // AUTOMATIC OFFBOARDING (OPE-2423). The signature above has authenticated the envelope, so its
1963
+ // `team_id` is the workspace that delivered this report. Every other decision — the
1964
+ // same-workspace gate, the tenant fence, the live users.info re-read, the terminal revoke and
1965
+ // its audit row — runs in core's offboardDeactivatedAccount, AFTER the ack: Slack wants a quick
1966
+ // 200, and a revoke is idempotent, so a Slack retry that races it changes nothing.
1967
+ const deactivation = parseSlackUserDeactivation(decision.env);
1968
+ if (!deactivation)
1969
+ return OK();
1970
+ // THE TENANT FENCE (OPE-1680), the same front-door refusal every other deciding branch takes.
1971
+ // Core's gate 2 ALSO requires a positive admission, because this fence is inert when config
1972
+ // declares no tenant — and a terminal revoke must not run on an inert answer.
1973
+ if (slackInteractivityTenantFenceDeclined({
1974
+ teamId: deactivation.deliveringTeamId,
1975
+ ...(deactivation.enterpriseId === undefined ? {} : { enterpriseId: deactivation.enterpriseId }),
1976
+ userId: deactivation.userId,
1977
+ }, "user-change", "front-user-change-branch")) {
1978
+ return fencedAck(OK());
1979
+ }
1980
+ args.waitUntil(routeUserDeactivation(deactivation).then((outcome) => console.log(`[open-everywhere:slack-front] user_change ${deactivation.userId}: offboarding ${outcome.kind}${outcome.kind === "refused" ? ` (${outcome.reason})` : ""}`)));
1981
+ return OK();
1982
+ }
1798
1983
  if (decision.kind === "reaction") {
1799
1984
  // Inbound reaction (feedback signal). Parse it; an unusable envelope is a no-op 200.
1800
1985
  const rev = parseSlackReactionEvent(decision.env);