@open-everywhere/provider-slack 0.6.0 → 0.8.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 (141) hide show
  1. package/agent/access/slack-attachment-fetch.ts +2 -1
  2. package/agent/app-manifest.ts +15 -1
  3. package/agent/channels/slack-agent-session.ts +249 -0
  4. package/agent/channels/slack-attachments.ts +20 -11
  5. package/agent/channels/slack-bot-ask.ts +101 -0
  6. package/agent/channels/slack-commands.ts +178 -17
  7. package/agent/channels/slack-context.ts +0 -5
  8. package/agent/channels/slack-events.ts +110 -33
  9. package/agent/channels/slack-follow-ups.ts +148 -0
  10. package/agent/channels/slack-friendly-names.ts +55 -0
  11. package/agent/channels/slack-front.ts +262 -27
  12. package/agent/channels/slack-home.ts +9 -3
  13. package/agent/channels/slack-identity.ts +9 -1
  14. package/agent/channels/slack-memory-canvas.ts +197 -54
  15. package/agent/channels/slack-origin-codec.ts +9 -0
  16. package/agent/channels/slack-post-arm.ts +68 -11
  17. package/agent/channels/slack-read.ts +27 -2
  18. package/agent/channels/slack-reply-blocks.ts +180 -0
  19. package/agent/channels/slack-reply-feedback.ts +75 -0
  20. package/agent/channels/slack-shortcut.ts +1 -1
  21. package/agent/channels/slack-voice-clips.ts +82 -0
  22. package/agent/channels/slack-wake-backscroll.ts +0 -5
  23. package/agent/channels/slack-web-api.ts +4 -2
  24. package/agent/channels/slack.ts +81 -19
  25. package/agent/docs-generated.ts +1282 -2
  26. package/agent/ops.ts +14 -21
  27. package/agent/register.ts +25 -0
  28. package/agent/setup/credentials.ts +17 -0
  29. package/agent/setup/page.ts +6 -3
  30. package/agent/surface-parity.ts +2 -0
  31. package/dist/agent/access/slack-attachment-fetch.d.ts.map +1 -1
  32. package/dist/agent/access/slack-attachment-fetch.js.map +1 -1
  33. package/dist/agent/app-manifest.d.ts.map +1 -1
  34. package/dist/agent/app-manifest.js +15 -1
  35. package/dist/agent/app-manifest.js.map +1 -1
  36. package/dist/agent/channels/slack-agent-session.d.ts +81 -0
  37. package/dist/agent/channels/slack-agent-session.d.ts.map +1 -0
  38. package/dist/agent/channels/slack-agent-session.js +198 -0
  39. package/dist/agent/channels/slack-agent-session.js.map +1 -0
  40. package/dist/agent/channels/slack-attachments.d.ts +11 -0
  41. package/dist/agent/channels/slack-attachments.d.ts.map +1 -1
  42. package/dist/agent/channels/slack-attachments.js +21 -14
  43. package/dist/agent/channels/slack-attachments.js.map +1 -1
  44. package/dist/agent/channels/slack-bot-ask.d.ts +30 -0
  45. package/dist/agent/channels/slack-bot-ask.d.ts.map +1 -0
  46. package/dist/agent/channels/slack-bot-ask.js +91 -0
  47. package/dist/agent/channels/slack-bot-ask.js.map +1 -0
  48. package/dist/agent/channels/slack-commands.d.ts +113 -10
  49. package/dist/agent/channels/slack-commands.d.ts.map +1 -1
  50. package/dist/agent/channels/slack-commands.js +151 -18
  51. package/dist/agent/channels/slack-commands.js.map +1 -1
  52. package/dist/agent/channels/slack-context.d.ts +1 -2
  53. package/dist/agent/channels/slack-context.d.ts.map +1 -1
  54. package/dist/agent/channels/slack-context.js +0 -4
  55. package/dist/agent/channels/slack-context.js.map +1 -1
  56. package/dist/agent/channels/slack-events.d.ts +47 -97
  57. package/dist/agent/channels/slack-events.d.ts.map +1 -1
  58. package/dist/agent/channels/slack-events.js +90 -22
  59. package/dist/agent/channels/slack-events.js.map +1 -1
  60. package/dist/agent/channels/slack-follow-ups.d.ts +44 -0
  61. package/dist/agent/channels/slack-follow-ups.d.ts.map +1 -0
  62. package/dist/agent/channels/slack-follow-ups.js +129 -0
  63. package/dist/agent/channels/slack-follow-ups.js.map +1 -0
  64. package/dist/agent/channels/slack-friendly-names.d.ts +10 -0
  65. package/dist/agent/channels/slack-friendly-names.d.ts.map +1 -0
  66. package/dist/agent/channels/slack-friendly-names.js +45 -0
  67. package/dist/agent/channels/slack-friendly-names.js.map +1 -0
  68. package/dist/agent/channels/slack-front.d.ts +38 -46
  69. package/dist/agent/channels/slack-front.d.ts.map +1 -1
  70. package/dist/agent/channels/slack-front.js +230 -23
  71. package/dist/agent/channels/slack-front.js.map +1 -1
  72. package/dist/agent/channels/slack-home.d.ts.map +1 -1
  73. package/dist/agent/channels/slack-home.js +10 -3
  74. package/dist/agent/channels/slack-home.js.map +1 -1
  75. package/dist/agent/channels/slack-identity.d.ts +7 -21
  76. package/dist/agent/channels/slack-identity.d.ts.map +1 -1
  77. package/dist/agent/channels/slack-identity.js +3 -1
  78. package/dist/agent/channels/slack-identity.js.map +1 -1
  79. package/dist/agent/channels/slack-memory-canvas.d.ts +21 -5
  80. package/dist/agent/channels/slack-memory-canvas.d.ts.map +1 -1
  81. package/dist/agent/channels/slack-memory-canvas.js +166 -55
  82. package/dist/agent/channels/slack-memory-canvas.js.map +1 -1
  83. package/dist/agent/channels/slack-origin-codec.d.ts.map +1 -1
  84. package/dist/agent/channels/slack-origin-codec.js +10 -0
  85. package/dist/agent/channels/slack-origin-codec.js.map +1 -1
  86. package/dist/agent/channels/slack-post-arm.d.ts +21 -1
  87. package/dist/agent/channels/slack-post-arm.d.ts.map +1 -1
  88. package/dist/agent/channels/slack-post-arm.js +57 -10
  89. package/dist/agent/channels/slack-post-arm.js.map +1 -1
  90. package/dist/agent/channels/slack-read.d.ts +11 -1
  91. package/dist/agent/channels/slack-read.d.ts.map +1 -1
  92. package/dist/agent/channels/slack-read.js +27 -3
  93. package/dist/agent/channels/slack-read.js.map +1 -1
  94. package/dist/agent/channels/slack-reply-blocks.d.ts +29 -0
  95. package/dist/agent/channels/slack-reply-blocks.d.ts.map +1 -0
  96. package/dist/agent/channels/slack-reply-blocks.js +172 -0
  97. package/dist/agent/channels/slack-reply-blocks.js.map +1 -0
  98. package/dist/agent/channels/slack-reply-feedback.d.ts +23 -0
  99. package/dist/agent/channels/slack-reply-feedback.d.ts.map +1 -0
  100. package/dist/agent/channels/slack-reply-feedback.js +63 -0
  101. package/dist/agent/channels/slack-reply-feedback.js.map +1 -0
  102. package/dist/agent/channels/slack-shortcut.d.ts +10 -0
  103. package/dist/agent/channels/slack-shortcut.d.ts.map +1 -1
  104. package/dist/agent/channels/slack-shortcut.js +1 -1
  105. package/dist/agent/channels/slack-shortcut.js.map +1 -1
  106. package/dist/agent/channels/slack-voice-clips.d.ts +16 -0
  107. package/dist/agent/channels/slack-voice-clips.d.ts.map +1 -0
  108. package/dist/agent/channels/slack-voice-clips.js +80 -0
  109. package/dist/agent/channels/slack-voice-clips.js.map +1 -0
  110. package/dist/agent/channels/slack-wake-backscroll.d.ts +0 -2
  111. package/dist/agent/channels/slack-wake-backscroll.d.ts.map +1 -1
  112. package/dist/agent/channels/slack-wake-backscroll.js +0 -4
  113. package/dist/agent/channels/slack-wake-backscroll.js.map +1 -1
  114. package/dist/agent/channels/slack-web-api.d.ts.map +1 -1
  115. package/dist/agent/channels/slack-web-api.js +4 -2
  116. package/dist/agent/channels/slack-web-api.js.map +1 -1
  117. package/dist/agent/channels/slack.d.ts +22 -1
  118. package/dist/agent/channels/slack.d.ts.map +1 -1
  119. package/dist/agent/channels/slack.js +70 -16
  120. package/dist/agent/channels/slack.js.map +1 -1
  121. package/dist/agent/docs-generated.d.ts.map +1 -1
  122. package/dist/agent/docs-generated.js +1282 -2
  123. package/dist/agent/docs-generated.js.map +1 -1
  124. package/dist/agent/ops.d.ts +1 -1
  125. package/dist/agent/ops.d.ts.map +1 -1
  126. package/dist/agent/ops.js +15 -21
  127. package/dist/agent/ops.js.map +1 -1
  128. package/dist/agent/register.d.ts.map +1 -1
  129. package/dist/agent/register.js +22 -1
  130. package/dist/agent/register.js.map +1 -1
  131. package/dist/agent/setup/credentials.d.ts +12 -0
  132. package/dist/agent/setup/credentials.d.ts.map +1 -1
  133. package/dist/agent/setup/credentials.js +17 -0
  134. package/dist/agent/setup/credentials.js.map +1 -1
  135. package/dist/agent/setup/page.d.ts.map +1 -1
  136. package/dist/agent/setup/page.js +6 -3
  137. package/dist/agent/setup/page.js.map +1 -1
  138. package/dist/agent/surface-parity.d.ts.map +1 -1
  139. package/dist/agent/surface-parity.js +2 -0
  140. package/dist/agent/surface-parity.js.map +1 -1
  141. package/package.json +40 -3
@@ -34,8 +34,10 @@
34
34
  import { defineChannel, POST } from "eve/channels";
35
35
  import { verifySlackSignature } from "./slack-front.js";
36
36
  import { slackSigningSecret } from "../setup/credentials.js";
37
- import { bindFrom, runOeCommand, oeSlash, parseSlackCommandText, resolvePartition, getOperationalStore, admittedTenantsFromConfig, unadmittedTenantLog, UNADMITTED_TENANT_DROP_REASON, } from "@open-everywhere/core/agent/adapter-api.js";
37
+ import { commandFailureText, bindFrom, runOeCommand, oeSlash, parseSlackCommandText, resolvePartition, auditSurfaceModeFrom, getOperationalStore, admittedTenantsFromConfig, unadmittedTenantLog, UNADMITTED_TENANT_DROP_REASON, } from "@open-everywhere/core/agent/adapter-api.js";
38
38
  import { slackTenantAdmission } from "./slack-tenant-fence.js";
39
+ import { slackAuthorIsMember, slackChannelFactsFor } from "./slack-events.js";
40
+ import { slackMode } from "./slack-identity.js";
39
41
  function log(msg) {
40
42
  console.log(`[open-everywhere:slack-commands] ${msg}`);
41
43
  }
@@ -59,16 +61,36 @@ function formField(params, name) {
59
61
  * reads — so a Grid declared once now answers here the same way it answers at every other door,
60
62
  * instead of resolving as though the line were absent.
61
63
  *
62
- * 🔴 STATE ITS REACH EXACTLY, because this door is narrower than the wake doors. For a CHANNEL
63
- * command it does NOT change `binding.trust`: this payload carries no `conversations.info` verdict,
64
- * so `slackTrust(undefined, undefined, "channel")` fails closed to `external`, and `bindFrom` takes
65
- * that raw verdict ahead of any vouch. So a channel `/oe` stays `trust: "external"` with the rung
66
- * and without it, and the budget scope `domainNameForScope` picks is unchanged. The rung reaches
67
- * `binding.trust` only on a DM-shaped `/oe` (a `D…` channel id), where the mapper leaves trust
68
- * undefined and the vouch is what answers. Spread conditionally, like every other door: a
69
- * single-workspace install stamps nothing. */
70
- export function bindableForSlashCommand(params) {
64
+ * 🔴 STATE ITS REACH EXACTLY. For a CHANNEL command the rung does NOT change `binding.trust`: the
65
+ * room's own verdict answers there (see below), and `bindFrom` takes that raw verdict ahead of any
66
+ * vouch. The rung reaches `binding.trust` only on a DM-shaped `/oe` (a `D…` channel id), and only
67
+ * when the invoker probe gave no verdict: the mapper then leaves trust undefined and the vouch
68
+ * answers (see below). Spread conditionally, like every other door: a single-workspace install
69
+ * stamps nothing.
70
+ *
71
+ * 🔴 A CHANNEL COMMAND CARRIES THE ROOM'S OWN VERDICT (OPE-2579). Slack's slash payload carries no
72
+ * sharing bit, so before this every channel `/oe` bound `slackTrust(undefined, undefined,
73
+ * "channel")`, which fails closed to `external`. A member in an internal channel was then refused
74
+ * `/oe suggest on` as an outsider. The route now passes {@link slashRoomVerdict}'s answer as
75
+ * `is_ext_shared` + `trust_checked`, the two attributes a channel message stamps from the same
76
+ * TTL-cached `conversations.info`. So a channel command reads the room's `internal` or `external` as a
77
+ * message in that room does. On the `person` leg (the default) the verdict is stamped only for an
78
+ * invoker `users.info` confirms a member. On the `room` leg it is stamped for anybody, because that
79
+ * leg answers the room's budget, not a member gate (OPE-2588, {@link bindSlashCommand}). No verdict
80
+ * stamps nothing, and the command stays fail-closed `external`.
81
+ *
82
+ * 🔴 A DM COMMAND CARRIES THE INVOKER'S OWN VERDICT (OPE-2579). In a 1:1 DM the invoker IS the
83
+ * partner, and the route passes {@link slashInvokerDmTrust}'s answer as `dm_partner_trust`, the
84
+ * attribute the chat DM leg stamps from the same `users.info` probe. Before this, a workspace vouch
85
+ * alone answered a DM command, so a guest or a Connect stranger in their DM with the app read
86
+ * `internal` here while the same person read `external` in a DM turn. A verdict outranks the vouch
87
+ * in both directions, exactly as in a DM turn: a guest reads `external` under a workspace vouch, and
88
+ * a confirmed member reads `internal` with no declaration at all. No verdict leaves the attribute
89
+ * unset and the binding resolves as before. This reaches every `/oe` command typed in a DM, not
90
+ * only `watch`. */
91
+ export function bindableForSlashCommand(params, invoker, leg = "person") {
71
92
  const enterpriseId = formField(params, "enterprise_id");
93
+ const room = invoker?.room && (leg === "room" || invoker.invokerMember === true) ? invoker.room : undefined;
72
94
  return {
73
95
  channel: { kind: "slack" },
74
96
  session: {
@@ -78,6 +100,8 @@ export function bindableForSlashCommand(params) {
78
100
  team_id: formField(params, "team_id") ?? "",
79
101
  channel_id: formField(params, "channel_id") ?? "",
80
102
  ...(enterpriseId ? { enterprise_id: enterpriseId } : {}),
103
+ ...(invoker?.dmPartnerTrust ? { dm_partner_trust: invoker.dmPartnerTrust } : {}),
104
+ ...(room ? { is_ext_shared: String(room.extShared), trust_checked: "true" } : {}),
81
105
  },
82
106
  principalId: formField(params, "user_id") ?? "",
83
107
  principalType: "slack-user",
@@ -86,6 +110,109 @@ export function bindableForSlashCommand(params) {
86
110
  },
87
111
  };
88
112
  }
113
+ /** How long each trust read (the invoker probe, the room read) may take before the route answers without
114
+ * it. Slack wants its ack inside three seconds, and `slackForm`'s 429 backoff can wait longer than that. */
115
+ const INVOKER_PROBE_MS = 1_500;
116
+ /**
117
+ * The invoker's own membership verdict for a 1:1 DM command, in `dm_partner_trust`'s vocabulary, or
118
+ * `{}` when there is none to give (OPE-2579). It is the chat DM leg's reading of the same probe
119
+ * (slack-front.ts `liveDmPartnerTrust`): `slackAuthorIsMember` decides, so the two doors cannot
120
+ * drift on what a guest is. A channel or group DM asks nothing here: there the ROOM's verdict is the
121
+ * binding's trust, and {@link slashRoomVerdict} reads it.
122
+ *
123
+ * 🔴 NO VERDICT IS NOT A VERDICT. No user id, no bot token, a refused `users.info`, a transport
124
+ * failure or a probe slower than {@link INVOKER_PROBE_MS} all answer `{}`, which leaves the binding
125
+ * exactly as it resolved before this probe existed. An unanswered probe never invents a guest, and
126
+ * never invents a member.
127
+ */
128
+ export async function slashInvokerDmTrust(params, probe = slackAuthorIsMember) {
129
+ const userId = formField(params, "user_id");
130
+ if (!userId || slackMode(undefined, formField(params, "channel_id")) !== "dm")
131
+ return {};
132
+ const member = await withinAckBudget(probe(userId, formField(params, "team_id")));
133
+ return member === undefined ? {} : { dmPartnerTrust: member ? "internal" : "external" };
134
+ }
135
+ /**
136
+ * A CHANNEL command's room verdict and invoker check, or `{}` when there is no room verdict to give
137
+ * (OPE-2579). The room read is `slackChannelFactsFor`, the TTL-cached `conversations.info` every
138
+ * channel wake reads, so the command door and the message door cannot disagree about one room.
139
+ *
140
+ * 🔴 THE INVOKER LEG, AND IT FAILS CLOSED. A channel message keeps the room's verdict on the auth and marks
141
+ * a guest author on the side (slack-events.ts `slackWakeAuthorFacts`), because one guest's message must not
142
+ * demote the channel's memory for everybody. A command has no session to protect: its binding exists for
143
+ * one answer, and `/oe suggest on` and `/oe watch more|less` read `binding.trust` as "is this person a
144
+ * member". So the route folds the author leg into the binding's `trust`, the composition Discord and
145
+ * Teams make: `invokerMember` is set only when `users.info` CONFIRMS the invoker a member, and the
146
+ * person's binding stamps the room's verdict only beside it. A guest, a Slack Connect stranger, and a
147
+ * person the probe could not check (no `users:read`, a refusal, a timeout) all leave `trust` fail-closed
148
+ * `external`. The message door fails OPEN on an unanswered probe because it marks a turn. Here `trust`
149
+ * IS the member gate, and a channel has no declaration to fall back to the way a DM command does.
150
+ *
151
+ * 🔴 THE ROOM'S VERDICT IS RETURNED FOR EVERY INVOKER (OPE-2588). `/oe budget` names the room's budget,
152
+ * and a channel's turns are charged under the room's domain, whoever typed them. So {@link bindSlashCommand}
153
+ * binds the room's verdict alone into `roomTrust`, and the budget reads that. A guest's `trust` is
154
+ * unchanged, and `/oe budget` reads both to refuse a guest in an internal channel (commands/core.ts
155
+ * `budgetWithheldFrom`). `/oe cover on` refuses outside a DM before it reads trust.
156
+ *
157
+ * 🔴 ONLY A ROOM IN THE CHANNEL MODE IS STAMPED. A 1:1 DM has its own leg ({@link slashInvokerDmTrust}).
158
+ * A group DM, or a room whose type Slack did not report, stamps nothing, so its binding is unchanged.
159
+ * Stamping a sharing verdict on a group DM the binding still calls a channel would mix two modes' rules.
160
+ *
161
+ * 🔴 NO VERDICT IS NOT A VERDICT. A failed or refused `conversations.info`, a response without the check,
162
+ * or a read slower than {@link INVOKER_PROBE_MS} answers `{}`. The command then binds `external`, as
163
+ * before this read existed. The room read and the invoker probe run in parallel inside one ack budget.
164
+ */
165
+ export async function slashRoomVerdict(params, roomFacts = slackChannelFactsFor, probe = slackAuthorIsMember) {
166
+ const channelId = formField(params, "channel_id");
167
+ if (!channelId || slackMode(undefined, channelId) === "dm")
168
+ return {};
169
+ const userId = formField(params, "user_id");
170
+ const [facts, member] = await Promise.all([
171
+ withinAckBudget(roomFacts(channelId)),
172
+ userId ? withinAckBudget(probe(userId, formField(params, "team_id"))) : Promise.resolve(undefined),
173
+ ]);
174
+ if (!facts || facts.trustChecked !== true || typeof facts.extShared !== "boolean")
175
+ return {};
176
+ if (facts.channelType !== "channel" && facts.channelType !== "group")
177
+ return {};
178
+ return { room: { extShared: facts.extShared }, ...(member === true ? { invokerMember: true } : {}) };
179
+ }
180
+ /** Both legs, for whichever kind of room the command came from. Never throws. */
181
+ export async function slashTrustFacts(params) {
182
+ return slackMode(undefined, formField(params, "channel_id")) === "dm" ? slashInvokerDmTrust(params) : slashRoomVerdict(params);
183
+ }
184
+ /**
185
+ * The slash command's binding, with the room's trust and the person's trust kept apart (OPE-2588).
186
+ *
187
+ * `trust` is the PERSON leg: the member gate `/oe suggest on`, `/oe watch more|less` and `/oe cover on`
188
+ * read. `roomTrust` is the ROOM leg: the same `bindFrom` walk over the room's verdict alone, so the
189
+ * declarations and the fail-closed default apply to it unchanged. `/oe budget` and the caps behind
190
+ * `raise` and `clear` read it through `roomTrustOf`. Before this the binding carried one value, so a
191
+ * guest in an internal channel read the external domain's budget while that channel's turns were
192
+ * charged under the internal domain. Now `/oe budget` refuses that guest, because a guest must not read
193
+ * an internal room's caps and spend (Tommy's ruling on #1431).
194
+ *
195
+ * In a DM both legs bind the same context, so the two values are equal. Every other field comes from
196
+ * the person's binding. The two bindings differ only in the two trust attributes, which move no key.
197
+ */
198
+ export function bindSlashCommand(params, facts) {
199
+ const person = bindFrom(bindableForSlashCommand(params, facts, "person"));
200
+ const room = bindFrom(bindableForSlashCommand(params, facts, "room"));
201
+ return { ...person, roomTrust: room.trust };
202
+ }
203
+ /** `p`'s answer, or `undefined` when it throws or takes longer than {@link INVOKER_PROBE_MS}. */
204
+ async function withinAckBudget(p) {
205
+ let timer;
206
+ const timeout = new Promise((resolve) => {
207
+ timer = setTimeout(() => resolve(undefined), INVOKER_PROBE_MS);
208
+ });
209
+ try {
210
+ return await Promise.race([p.catch(() => undefined), timeout]);
211
+ }
212
+ finally {
213
+ clearTimeout(timer);
214
+ }
215
+ }
89
216
  /**
90
217
  * Make a refused slash command OBSERVABLE, the same way `slack.ts`'s `auditWakeDropped` makes a
91
218
  * refused wake observable: the webhook function's console output never reaches `vercel logs`, so
@@ -105,16 +232,18 @@ export function bindableForSlashCommand(params) {
105
232
  */
106
233
  async function auditCommandDropped(teamId, channelId, reason, enterpriseId) {
107
234
  try {
108
- const p = resolvePartition({
235
+ const bindable = {
109
236
  channel: { kind: "slack" },
110
237
  session: { auth: { current: { attributes: { team_id: teamId ?? "", channel_id: channelId ?? "" }, principalId: "", principalType: "slack-user" } } },
111
- });
238
+ };
239
+ const p = resolvePartition(bindable);
112
240
  await getOperationalStore().appendAudit({
113
241
  ts: new Date().toISOString(),
114
242
  org: p.org,
115
243
  platform: p.platform,
116
244
  workspace: p.workspace,
117
245
  surface: p.surface,
246
+ ...auditSurfaceModeFrom(bindable),
118
247
  action: "surface.wake_dropped",
119
248
  detail: { reason, door: "slash-command", channel: channelId ?? null, team: teamId ?? null, enterprise: enterpriseId ?? null },
120
249
  });
@@ -124,6 +253,10 @@ async function auditCommandDropped(teamId, channelId, reason, enterpriseId) {
124
253
  }
125
254
  }
126
255
  function ephemeralResponse(text) {
256
+ // OPE-2490: an empty reply means the command's card posted in this channel and IS the answer. An
257
+ // empty 200 acknowledges the command, and Slack then shows nothing beside the card.
258
+ if (text.length === 0)
259
+ return new Response(null, { status: 200 });
127
260
  return new Response(JSON.stringify({ response_type: "ephemeral", text }), {
128
261
  status: 200,
129
262
  headers: { "content-type": "application/json" },
@@ -196,18 +329,18 @@ export default defineChannel({
196
329
  return ephemeralResponse(`This endpoint only handles "${expected}" — check your Slack app's Slash Command configuration.`);
197
330
  }
198
331
  const cmd = parseSlackCommandText(formField(params, "text"));
199
- const binding = bindFrom(bindableForSlashCommand(params));
332
+ const binding = bindSlashCommand(params, await slashTrustFacts(params));
200
333
  try {
201
334
  const reply = await runOeCommand(cmd, binding, { attachSession });
202
335
  return ephemeralResponse(reply);
203
336
  }
204
337
  catch (err) {
205
- // runOeCommand's budget-raise/clear branches can throw a user-facing validation error
206
- // (e.g. proposing from a DM with no explicit scope) — surface it verbatim. Never let a
207
- // thrown error escape as a 500; Slack's slash-command UX for that is an ugly
208
- // "operation_timeout"/dispatch_failed toast.
338
+ // A PersonFacingError is already worded for the person — it renders as-is. Anything else
339
+ // (a store or network failure, a planner's model-facing refusal) renders the generic line,
340
+ // and its message goes to the log only (OPE-2486). Never let a thrown error escape as a
341
+ // 500; Slack's slash-command UX for that is an ugly "operation_timeout"/dispatch_failed toast.
209
342
  log(`"${expected}" command failed softly: ${String(err)}`);
210
- return ephemeralResponse(`Couldn't complete that: ${err instanceof Error ? err.message : String(err)}`);
343
+ return ephemeralResponse(commandFailureText(err));
211
344
  }
212
345
  }),
213
346
  ],
@@ -1 +1 @@
1
- {"version":3,"file":"slack-commands.js","sourceRoot":"","sources":["../../../agent/channels/slack-commands.ts"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,8FAA8F;AAC9F,uFAAuF;AACvF,iFAAiF;AACjF,EAAE;AACF,sFAAsF;AACtF,4FAA4F;AAC5F,+FAA+F;AAC/F,6FAA6F;AAC7F,8FAA8F;AAC9F,oFAAoF;AACpF,4FAA4F;AAC5F,sFAAsF;AACtF,EAAE;AACF,0FAA0F;AAC1F,8FAA8F;AAC9F,qFAAqF;AACrF,8FAA8F;AAC9F,mCAAmC;AACnC,EAAE;AACF,6FAA6F;AAC7F,6FAA6F;AAC7F,6FAA6F;AAC7F,8FAA8F;AAC9F,qFAAqF;AACrF,6FAA6F;AAC7F,EAAE;AACF,iFAAiF;AACjF,EAAE;AACF,iGAAiG;AACjG,8FAA8F;AAC9F,iGAAiG;AACjG,sDAAsD;AAEtD,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,OAAO,EACP,qBAAqB,EACrB,gBAAgB,EAChB,mBAAmB,EACnB,yBAAyB,EACzB,mBAAmB,EACnB,6BAA6B,GAE9B,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAE/D,SAAS,GAAG,CAAC,GAAW;IACtB,OAAO,CAAC,GAAG,CAAC,oCAAoC,GAAG,EAAE,CAAC,CAAC;AACzD,CAAC;AAED,mGAAmG;AACnG,MAAM,CAAC,MAAM,oBAAoB,GAAG,wBAAwB,CAAC;AAE7D;oFACoF;AACpF,SAAS,SAAS,CAAC,MAAuB,EAAE,IAAY;IACtD,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC3B,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3C,CAAC;AAED;;;;;;;;;;;;;;;;;;;+CAmB+C;AAC/C,MAAM,UAAU,uBAAuB,CAAC,MAAuB;IAC7D,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACxD,OAAO;QACL,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE;QAC1B,OAAO,EAAE;YACP,IAAI,EAAE;gBACJ,OAAO,EAAE;oBACP,UAAU,EAAE;wBACV,OAAO,EAAE,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,IAAI,EAAE;wBAC3C,UAAU,EAAE,SAAS,CAAC,MAAM,EAAE,YAAY,CAAC,IAAI,EAAE;wBACjD,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;qBACzD;oBACD,WAAW,EAAE,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,IAAI,EAAE;oBAC/C,aAAa,EAAE,YAAY;iBAC5B;aACF;SACF;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,KAAK,UAAU,mBAAmB,CAAC,MAA0B,EAAE,SAA6B,EAAE,MAAc,EAAE,YAAqB;IACjI,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,gBAAgB,CAAC;YACzB,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE;YAC1B,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,MAAM,IAAI,EAAE,EAAE,UAAU,EAAE,SAAS,IAAI,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,aAAa,EAAE,YAAY,EAAE,EAAE,EAAE;SAClI,CAAC,CAAC;QACtB,MAAM,mBAAmB,EAAE,CAAC,WAAW,CAAC;YACtC,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAC5B,GAAG,EAAE,CAAC,CAAC,GAAG;YACV,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,MAAM,EAAE,sBAAsB;YAC9B,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,SAAS,IAAI,IAAI,EAAE,IAAI,EAAE,MAAM,IAAI,IAAI,EAAE,UAAU,EAAE,YAAY,IAAI,IAAI,EAAE;SAC9H,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,wBAAwB;IAC1B,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAY;IACrC,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,aAAa,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,EAAE;QACxE,MAAM,EAAE,GAAG;QACX,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;KAChD,CAAC,CAAC;AACL,CAAC;AAED,eAAe,aAAa,CAAC;IAC3B,MAAM,EAAE;QACN,4FAA4F;QAC5F,0FAA0F;QAC1F,qEAAqE;QACrE,IAAI,CAAC,oBAAoB,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,EAAE,EAAE;YACrE,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YACjC,+FAA+F;YAC/F,gGAAgG;YAChG,yFAAyF;YACzF,IAAI,CAAC,oBAAoB,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,MAAM,kBAAkB,EAAE,CAAC,EAAE,CAAC;gBAC5E,OAAO,IAAI,QAAQ,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;YACvD,CAAC;YAED,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,OAAO,CAAC,CAAC;YAC5C,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;YAE5C,6FAA6F;YAC7F,6FAA6F;YAC7F,6FAA6F;YAC7F,+FAA+F;YAC/F,0FAA0F;YAC1F,4CAA4C;YAC5C,EAAE;YACF,2FAA2F;YAC3F,0FAA0F;YAC1F,+FAA+F;YAC/F,0FAA0F;YAC1F,EAAE;YACF,8FAA8F;YAC9F,iFAAiF;YACjF,uFAAuF;YACvF,2FAA2F;YAC3F,2FAA2F;YAC3F,2FAA2F;YAC3F,2BAA2B;YAC3B,EAAE;YACF,0FAA0F;YAC1F,uFAAuF;YACvF,mCAAmC;YACnC,EAAE;YACF,2FAA2F;YAC3F,4FAA4F;YAC5F,4FAA4F;YAC5F,2FAA2F;YAC3F,2DAA2D;YAC3D,EAAE;YACF,4FAA4F;YAC5F,4FAA4F;YAC5F,8CAA8C;YAC9C,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;YACxD,IAAI,oBAAoB,CAAC,MAAM,EAAE,YAAY,CAAC,KAAK,YAAY,EAAE,CAAC;gBAChE,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,yBAAyB,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;gBACpG,SAAS,CAAC,mBAAmB,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,6BAA6B,EAAE,YAAY,CAAC,CAAC,CAAC;gBACrH,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;YAC7C,CAAC;YAED,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;YAC7C,0FAA0F;YAC1F,gFAAgF;YAChF,MAAM,QAAQ,GAAG,OAAO,EAAE,CAAC;YAC3B,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;gBACzB,+FAA+F;gBAC/F,oFAAoF;gBACpF,qFAAqF;gBACrF,0DAA0D;gBAC1D,GAAG,CAAC,6BAA6B,OAAO,IAAI,GAAG,aAAa,QAAQ,qDAAqD,CAAC,CAAC;gBAC3H,OAAO,iBAAiB,CAAC,+BAA+B,QAAQ,yDAAyD,CAAC,CAAC;YAC7H,CAAC;YAED,MAAM,GAAG,GAAG,qBAAqB,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;YAC7D,MAAM,OAAO,GAAG,QAAQ,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC,CAAC;YAC1D,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,CAAC,CAAC;gBAClE,OAAO,iBAAiB,CAAC,KAAK,CAAC,CAAC;YAClC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,sFAAsF;gBACtF,uFAAuF;gBACvF,6EAA6E;gBAC7E,6CAA6C;gBAC7C,GAAG,CAAC,IAAI,QAAQ,4BAA4B,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC3D,OAAO,iBAAiB,CAAC,2BAA2B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC1G,CAAC;QACH,CAAC,CAAC;KACH;CACF,CAAC,CAAC"}
1
+ {"version":3,"file":"slack-commands.js","sourceRoot":"","sources":["../../../agent/channels/slack-commands.ts"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,8FAA8F;AAC9F,uFAAuF;AACvF,iFAAiF;AACjF,EAAE;AACF,sFAAsF;AACtF,4FAA4F;AAC5F,+FAA+F;AAC/F,6FAA6F;AAC7F,8FAA8F;AAC9F,oFAAoF;AACpF,4FAA4F;AAC5F,sFAAsF;AACtF,EAAE;AACF,0FAA0F;AAC1F,8FAA8F;AAC9F,qFAAqF;AACrF,8FAA8F;AAC9F,mCAAmC;AACnC,EAAE;AACF,6FAA6F;AAC7F,6FAA6F;AAC7F,6FAA6F;AAC7F,8FAA8F;AAC9F,qFAAqF;AACrF,6FAA6F;AAC7F,EAAE;AACF,iFAAiF;AACjF,EAAE;AACF,iGAAiG;AACjG,8FAA8F;AAC9F,iGAAiG;AACjG,sDAAsD;AAEtD,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EACL,kBAAkB,EAClB,QAAQ,EACR,YAAY,EACZ,OAAO,EACP,qBAAqB,EACrB,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,EACnB,yBAAyB,EACzB,mBAAmB,EACnB,6BAA6B,GAG9B,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD,SAAS,GAAG,CAAC,GAAW;IACtB,OAAO,CAAC,GAAG,CAAC,oCAAoC,GAAG,EAAE,CAAC,CAAC;AACzD,CAAC;AAED,mGAAmG;AACnG,MAAM,CAAC,MAAM,oBAAoB,GAAG,wBAAwB,CAAC;AAE7D;oFACoF;AACpF,SAAS,SAAS,CAAC,MAAuB,EAAE,IAAY;IACtD,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC3B,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3C,CAAC;AAiBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAsCoB;AACpB,MAAM,UAAU,uBAAuB,CAAC,MAAuB,EAAE,OAAyB,EAAE,GAAG,GAAkB,QAAQ;IACvH,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,KAAK,MAAM,IAAI,OAAO,CAAC,aAAa,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5G,OAAO;QACL,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE;QAC1B,OAAO,EAAE;YACP,IAAI,EAAE;gBACJ,OAAO,EAAE;oBACP,UAAU,EAAE;wBACV,OAAO,EAAE,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,IAAI,EAAE;wBAC3C,UAAU,EAAE,SAAS,CAAC,MAAM,EAAE,YAAY,CAAC,IAAI,EAAE;wBACjD,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBACxD,GAAG,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBAChF,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;qBAClF;oBACD,WAAW,EAAE,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,IAAI,EAAE;oBAC/C,aAAa,EAAE,YAAY;iBAC5B;aACF;SACF;KACF,CAAC;AACJ,CAAC;AAED;6GAC6G;AAC7G,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAE/B;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,MAAuB,EACvB,KAAK,GAAiF,mBAAmB;IAEzG,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM,IAAI,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,KAAK,IAAI;QAAE,OAAO,EAAE,CAAC;IACzF,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IAClF,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;AAC1F,CAAC;AAKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAuB,EACvB,SAAS,GAAmB,oBAAoB,EAChD,KAAK,GAAiF,mBAAmB;IAEzG,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAClD,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,KAAK,IAAI;QAAE,OAAO,EAAE,CAAC;IACtE,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC5C,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACxC,eAAe,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACrC,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC;KACnG,CAAC,CAAC;IACH,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,YAAY,KAAK,IAAI,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IAC7F,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS,IAAI,KAAK,CAAC,WAAW,KAAK,OAAO;QAAE,OAAO,EAAE,CAAC;IAChF,OAAO,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,EAAE,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,IAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AAChH,CAAC;AAED,iFAAiF;AACjF,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAAuB;IAC3D,OAAO,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;AACjI,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAuB,EAAE,KAAsB;IAC9E,MAAM,MAAM,GAAG,QAAQ,CAAC,uBAAuB,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC1E,MAAM,IAAI,GAAG,QAAQ,CAAC,uBAAuB,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IACtE,OAAO,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;AAC9C,CAAC;AAED,iGAAiG;AACjG,KAAK,UAAU,eAAe,CAAI,CAAa;IAC7C,IAAI,KAAgD,CAAC;IACrD,MAAM,OAAO,GAAG,IAAI,OAAO,CAAY,CAAC,OAAO,EAAE,EAAE;QACjD,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,gBAAgB,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IACH,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IACjE,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,KAAK,UAAU,mBAAmB,CAAC,MAA0B,EAAE,SAA6B,EAAE,MAAc,EAAE,YAAqB;IACjI,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG;YACf,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE;YAC1B,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,MAAM,IAAI,EAAE,EAAE,UAAU,EAAE,SAAS,IAAI,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,aAAa,EAAE,YAAY,EAAE,EAAE,EAAE;SAClI,CAAC;QACrB,MAAM,CAAC,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QACrC,MAAM,mBAAmB,EAAE,CAAC,WAAW,CAAC;YACtC,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAC5B,GAAG,EAAE,CAAC,CAAC,GAAG;YACV,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,GAAG,oBAAoB,CAAC,QAAQ,CAAC;YACjC,MAAM,EAAE,sBAAsB;YAC9B,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,SAAS,IAAI,IAAI,EAAE,IAAI,EAAE,MAAM,IAAI,IAAI,EAAE,UAAU,EAAE,YAAY,IAAI,IAAI,EAAE;SAC9H,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,wBAAwB;IAC1B,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAY;IACrC,iGAAiG;IACjG,oFAAoF;IACpF,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IAClE,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,aAAa,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,EAAE;QACxE,MAAM,EAAE,GAAG;QACX,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;KAChD,CAAC,CAAC;AACL,CAAC;AAED,eAAe,aAAa,CAAC;IAC3B,MAAM,EAAE;QACN,4FAA4F;QAC5F,0FAA0F;QAC1F,qEAAqE;QACrE,IAAI,CAAC,oBAAoB,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,EAAE,EAAE;YACrE,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YACjC,+FAA+F;YAC/F,gGAAgG;YAChG,yFAAyF;YACzF,IAAI,CAAC,oBAAoB,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,MAAM,kBAAkB,EAAE,CAAC,EAAE,CAAC;gBAC5E,OAAO,IAAI,QAAQ,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;YACvD,CAAC;YAED,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,OAAO,CAAC,CAAC;YAC5C,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;YAE5C,6FAA6F;YAC7F,6FAA6F;YAC7F,6FAA6F;YAC7F,+FAA+F;YAC/F,0FAA0F;YAC1F,4CAA4C;YAC5C,EAAE;YACF,2FAA2F;YAC3F,0FAA0F;YAC1F,+FAA+F;YAC/F,0FAA0F;YAC1F,EAAE;YACF,8FAA8F;YAC9F,iFAAiF;YACjF,uFAAuF;YACvF,2FAA2F;YAC3F,2FAA2F;YAC3F,2FAA2F;YAC3F,2BAA2B;YAC3B,EAAE;YACF,0FAA0F;YAC1F,uFAAuF;YACvF,mCAAmC;YACnC,EAAE;YACF,2FAA2F;YAC3F,4FAA4F;YAC5F,4FAA4F;YAC5F,2FAA2F;YAC3F,2DAA2D;YAC3D,EAAE;YACF,4FAA4F;YAC5F,4FAA4F;YAC5F,8CAA8C;YAC9C,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;YACxD,IAAI,oBAAoB,CAAC,MAAM,EAAE,YAAY,CAAC,KAAK,YAAY,EAAE,CAAC;gBAChE,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,yBAAyB,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;gBACpG,SAAS,CAAC,mBAAmB,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,6BAA6B,EAAE,YAAY,CAAC,CAAC,CAAC;gBACrH,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;YAC7C,CAAC;YAED,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;YAC7C,0FAA0F;YAC1F,gFAAgF;YAChF,MAAM,QAAQ,GAAG,OAAO,EAAE,CAAC;YAC3B,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;gBACzB,+FAA+F;gBAC/F,oFAAoF;gBACpF,qFAAqF;gBACrF,0DAA0D;gBAC1D,GAAG,CAAC,6BAA6B,OAAO,IAAI,GAAG,aAAa,QAAQ,qDAAqD,CAAC,CAAC;gBAC3H,OAAO,iBAAiB,CAAC,+BAA+B,QAAQ,yDAAyD,CAAC,CAAC;YAC7H,CAAC;YAED,MAAM,GAAG,GAAG,qBAAqB,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;YAC7D,MAAM,OAAO,GAAG,gBAAgB,CAAC,MAAM,EAAE,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;YACxE,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,CAAC,CAAC;gBAClE,OAAO,iBAAiB,CAAC,KAAK,CAAC,CAAC;YAClC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,yFAAyF;gBACzF,2FAA2F;gBAC3F,wFAAwF;gBACxF,+FAA+F;gBAC/F,GAAG,CAAC,IAAI,QAAQ,4BAA4B,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC3D,OAAO,iBAAiB,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC;YACpD,CAAC;QACH,CAAC,CAAC;KACH;CACF,CAAC,CAAC"}
@@ -1,7 +1,6 @@
1
1
  import type { SlackContext } from "eve/channels/slack";
2
2
  import type { SlackMessage } from "eve/channels/slack";
3
- import { renderContext, type ContextLine } from "@open-everywhere/core/agent/adapter-api.js";
4
- export { renderContext, type ContextLine };
3
+ import { type ContextLine } from "@open-everywhere/core/agent/adapter-api.js";
5
4
  export declare function readMoreHint(): string;
6
5
  /**
7
6
  * Map raw Slack message objects (from `conversations.history` / `conversations.replies` — raw
@@ -1 +1 @@
1
- {"version":3,"file":"slack-context.d.ts","sourceRoot":"","sources":["../../../agent/channels/slack-context.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAgB,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,4CAA4C,CAAC;AAK3G,OAAO,EAAE,aAAa,EAAE,KAAK,WAAW,EAAE,CAAC;AAmB3C,wBAAgB,YAAY,IAAI,MAAM,CAKrC;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAC3C,GAAG,EAAE;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACzD,WAAW,EAAE,CAiBf;AA0BD,kDAAkD;AAClD,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C;AAgDD;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAKzG"}
1
+ {"version":3,"file":"slack-context.d.ts","sourceRoot":"","sources":["../../../agent/channels/slack-context.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAA+B,KAAK,WAAW,EAAE,MAAM,4CAA4C,CAAC;AAmB3G,wBAAgB,YAAY,IAAI,MAAM,CAKrC;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAC3C,GAAG,EAAE;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACzD,WAAW,EAAE,CAiBf;AA0BD,kDAAkD;AAClD,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C;AAgDD;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAKzG"}
@@ -34,10 +34,6 @@
34
34
  // stays here and is fed into renderContext; a surface with no read tools passes no hint.
35
35
  import { loadThreadContextMessages } from "eve/channels/slack";
36
36
  import { MAX_MESSAGES, renderContext } from "@open-everywhere/core/agent/adapter-api.js";
37
- // Re-export the shared render + line shape so slack-wake-backscroll.ts (which imports them from
38
- // here) keeps compiling unchanged after the extraction, and any future Slack consumer has one
39
- // import site. The mapping (`linesFromMessages`) is defined below — it's Slack-message-shaped.
40
- export { renderContext };
41
37
  // When the rendered slice fills MAX_MESSAGES exactly, there's very likely more history above
42
38
  // it (both fetchers below request MAX_MESSAGES-worth from Slack, so filling the cap usually
43
39
  // means older messages were left out) — tell the model this is a bounded slice, not the whole
@@ -1 +1 @@
1
- {"version":3,"file":"slack-context.js","sourceRoot":"","sources":["../../../agent/channels/slack-context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"slack-context.js","sourceRoot":"","sources":["../../../agent/channels/slack-context.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,8 @@
1
1
  import { type SlackAppContextRoom } from "./slack-side-panel.js";
2
- import { resolvePartition, type AttachSessionForCancel, type SeatCatchUpRequest, type SeatCatchUpResult, type ExternalPolicy, type IngestedChatMessage, PREFER_NO_REPLY_TOOL, type Partition, type BindableContext, type SingleWindowMentionPolicy, type UnifiedWindowWake, type ReplyDecision, type EngagementRow, type RoomRoster, type ContextLine, type WakeAttachment, type WakeMessageInput, type WakeParticipant, type WakeTrust, type NormalizedWake, type WakeEngagementTier } from "@open-everywhere/core/agent/adapter-api.js";
3
- import { type SpendGateDecision } from "./slack-spend-gate.js";
2
+ import { resolvePartition, type AttachSessionForCancel, type SeatCatchUpRequest, type SeatCatchUpResult, type ExternalPolicy, type IngestedChatMessage, type Partition, type BindableContext, type SingleWindowMentionPolicy, type UnifiedWindowWake, type ReplyDecision, type EngagementRow, type RoomRoster, type ContextLine, type WakeAttachment, type WakeMessageInput, type WakeParticipant, type WakeTrust, type NormalizedWake, type WakeEngagementTier } from "@open-everywhere/core/agent/adapter-api.js";
4
3
  import { type WakeBackscrollLines } from "./slack-wake-backscroll.js";
5
- export { PREFER_NO_REPLY_TOOL };
6
4
  import { type E2eDriverIdentity, type FinalMessageAction, type ReactionSinkDeps, type ReactionIngestOutcome, type ReactionVerb } from "@open-everywhere/core/agent/adapter-api.js";
5
+ import type { AuditDetail } from "@open-everywhere/core/agent/adapter-api.js";
7
6
  /**
8
7
  * Minimal Slack `event_callback` envelope shape (the subset the parser reads). Mirrors
9
8
  * Eve's internal `SlackEventCallback` without depending on a type it doesn't re-export.
@@ -95,6 +94,12 @@ export interface ParsedMessageEvent {
95
94
  * wake envelope's `<previous-body>` (wake-envelope.ts) so a judged turn can diff old↔new.
96
95
  */
97
96
  readonly previousText?: string;
97
+ /**
98
+ * TRUE ⇒ a `message_changed` edit whose words and files are exactly the pre-edit ones
99
+ * ({@link isUnchangedSlackEdit}). Absent on every other event, and on an edit that carries no
100
+ * `previous_message` to compare against, so an unknown edit reads as a real one.
101
+ */
102
+ readonly unchangedEdit?: true;
98
103
  /** True when the text @mentions the bot — those go through the normal mention path. */
99
104
  readonly isAppMention: boolean;
100
105
  /** Image/file attachment REFERENCES parsed off Slack's `files[]` (docs Part B) — surfaced in
@@ -175,6 +180,29 @@ export declare function resolveSlackInboundText(text: string, inner: Record<stri
175
180
  * ids, wrong outer type). Pure — no I/O — so it's trivially testable against fixtures.
176
181
  */
177
182
  export declare function parseMessageEvent(envelope: SlackEventEnvelope): ParsedMessageEvent | null;
183
+ /**
184
+ * Does a `message_changed` edit leave the message's WORDS and FILES as they were? Pure.
185
+ *
186
+ * 🔴 WHY THIS EXISTS (OPE-2577). Slack raises `message_changed` for more than a person's edit. It
187
+ * raises one each time the message's METADATA changes: a link unfurl, and, in the person's DM with
188
+ * the app, each `agents.sessions.setStatus` call that OE itself makes on the session's root message
189
+ * (slack-agent-session.ts: the title at the door, `processing` at turn start, `active` or
190
+ * `suspended` at the park). The event is hidden: `conversations.history` never lists it, and its
191
+ * `ts` is a fresh notice stamp. Its inner message is the person's own message, with the person's
192
+ * own author. So before this predicate, the DM door woke the seat on every one of them, as a NEW
193
+ * inbound wake. Ship #252 measured it: one DM drew three more wakes within 15 seconds, the
194
+ * reply-freshness gate refused the answer to the person's real wake as `stale-conversation`, and the
195
+ * answer landed under a later edit wake. A voice clip was lost, because an edit is never heard again
196
+ * (slack-voice-clips.ts).
197
+ *
198
+ * An edit that changes no words and no files says nothing new, so no door wakes on it. A REAL edit
199
+ * still wakes: any difference in the typed text, in the quoted-message text Slack parks in
200
+ * `attachments[]` ({@link resolveSlackInboundText}), or in a file's id or its tombstone mark (a deleted file
201
+ * stays as `mode: "tombstone"`) makes this false.
202
+ */
203
+ export declare function isUnchangedSlackEdit(inner: Record<string, unknown>, previous: Record<string, unknown>): boolean;
204
+ /** The log reason both Slack wake doors give when they drop an {@link isUnchangedSlackEdit} edit. */
205
+ export declare const UNCHANGED_EDIT_DROP_REASON = "an edit that changed no words and no files (a metadata-only message_changed) \u2014 not news";
178
206
  /** A fail-soft profile resolver: raw platform user id → {real name, self-set handle}, or
179
207
  * undefined. Injected on each route's deps so name resolution is unit-testable AND so a caller
180
208
  * that omits it (or the resolver throwing) degrades to raw ids — a name lookup must NEVER block
@@ -352,38 +380,6 @@ export declare function slackThreadFollowWake(ev: ParsedMessageEvent, opts: Slac
352
380
  * kept the @mention — the ADDRESSED `direct-mention` addressing, which keeps the envelope and its
353
381
  * wake-id and tells the standing block this wake is owed an answer. */
354
382
  export declare function slackChannelWatchWake(ev: ParsedMessageEvent, opts: SlackWakeOpts): NormalizedWake;
355
- /**
356
- * THE DM WAKE (OPE-351 stage 2; group DMs added at stage 4) — the first producer of the `dm` envelope
357
- * reason, which has been in the vocabulary (channels/wake-envelope.ts {@link WakeReason}) since it was
358
- * reverse-engineered from Tag with no emitter behind it.
359
- *
360
- * ADDRESSING IS `direct-mention`, ALWAYS, and it is doing two jobs at once. Semantically it is simply
361
- * TRUE for a 1:1: everything said in a 1:1 DM is said to the agent, so a DM is never judged for whether
362
- * it was addressed — the engagement-tier dial, the name-drop judge and the channel-watch silence bias
363
- * are all category errors here (slack-front.ts routes a DM around routeSupervisorEvent entirely for that
364
- * reason). Mechanically it is LOAD-BEARING: `direct-mention` is what stamps `oe_addressing` through
365
- * the divert, which marks the wake as OWED a reply. It selects the `[direct]` preamble, whose reply
366
- * mandate names the wake-id the model must echo back, and it classifies the drop row if the turn
367
- * ends in prose anyway.
368
- * 🔴 IT IS NOT A DELIVERY PATH (OPE-1982). It used to arm the unified channel's addressed-prose
369
- * bridge, so a DM answer written as prose instead of a `reply` call still reached the room. That
370
- * bridge is deleted: on the unified channel a turn's closing prose is DROPPED on every addressing
371
- * and re-driven once towards the tool, so a DM answer reaches its room only through a `reply` call.
372
- *
373
- * A GROUP DM IS THE SAME WAKE. The addressing is identical (the drop classification and the reply mandate
374
- * are needed just the same), and the room shape reaches the model on `<channel type="mpim">` against
375
- * a 1:1's `type="im"`. The old `groupDm` flag selected the opening clause of a PROSE preamble that no
376
- * longer exists, so OPE-770 deleted it — the schema render has no prose to select. The silence escape
377
- * the reply mandate carries is what makes unconditional WAKING compatible with conditional REPLYING
378
- * in a room that also holds other humans.
379
- *
380
- * `reason` is `dm` rather than `mention` because the envelope's reason describes the SURFACE SHAPE the
381
- * wake arrived on, and telling a DM it was "@mentioned" is a small lie that costs orientation. A group
382
- * DM keeps `dm` for the same reason: {@link WakeReason}'s own definition is "a direct-message-EQUIVALENT
383
- * surface", which an mpim is — inventing a fourth value for it would extrapolate a Tag-derived
384
- * vocabulary with no evidence behind the new entry.
385
- */
386
- export declare function slackDmWake(ev: ParsedMessageEvent, opts: SlackWakeOpts): NormalizedWake;
387
383
  /**
388
384
  * What `message.completed` (channels/slack.ts) should actually DO with a terminal
389
385
  * {@link FinalMessageAction} ("silent" or "post" — never "buffer-tool-status", which is
@@ -441,7 +437,7 @@ export interface MessageRouteDeps {
441
437
  */
442
438
  readonly confirmInternal?: (channelId: string) => Promise<boolean>;
443
439
  /** Append a durable audit row. Optional; best-effort. */
444
- readonly audit?: (action: string, detail: Record<string, unknown>) => Promise<void>;
440
+ readonly audit?: (action: string, detail: AuditDetail) => Promise<void>;
445
441
  /** Resolve the trigger author's display name for the envelope (fail-soft). Optional so
446
442
  * existing test doubles keep compiling AND so a wake never depends on a name lookup — absent
447
443
  * or throwing ⇒ the raw id renders. Live wiring points this at {@link fetchUserProfileNames}. */
@@ -452,6 +448,16 @@ export interface RouteOutcome extends ReplyDecision {
452
448
  readonly woke: boolean;
453
449
  }
454
450
  export declare function bindableFor(ev: ParsedMessageEvent): BindableContext;
451
+ /** {@link bindableFor} over BARE IDS, for an ingress that has no {@link ParsedMessageEvent} to read
452
+ * them off — the interactivity CLICK routes (OPE-1680), which carry a signed payload rather than a
453
+ * message. ONE builder, so a row written from a click keys to the same partition a message from the
454
+ * same room would. */
455
+ export declare function bindableForSlackIds(ids: {
456
+ readonly teamId?: string | undefined;
457
+ readonly channelId: string;
458
+ readonly channelType?: string | undefined;
459
+ readonly userId?: string | undefined;
460
+ }): BindableContext;
455
461
  /**
456
462
  * Route one parsed message event: apply the delivery policy and, if it passes, wake the
457
463
  * engaged thread's session. Returns the decision + whether a wake fired. All side effects
@@ -475,28 +481,6 @@ export type WakeSend = (input: {
475
481
  continuationToken: string;
476
482
  state?: unknown;
477
483
  }) => Promise<unknown>;
478
- /**
479
- * The SPEND GATE at the ENGAGEMENT door (OPE-33) — the second call site of the ONE gate
480
- * (slack-spend-gate.ts); the first is slack.ts `onInbound` (the mention door).
481
- *
482
- * WHY BOTH: on eve 0.27.5 the compiled slackChannel drops self-authored messages
483
- * (`isSelfAuthoredSlackMessage`, matching `raw.app_id` against the envelope's `api_app_id`)
484
- * BEFORE `onAppMention`/`onDirectMessage` run — and Slack stamps `app_id` on anything an app
485
- * posts through the Web API, user token included. Every driver-app-authored mention therefore
486
- * skips the mention door entirely and re-enters through THIS path (live-proven 2026-07-25:
487
- * capped surfaces never refused). Gating only the mention handler is gating one of two doors.
488
- *
489
- * Refuse-and-drop semantics mirror the mention door exactly: over cap + no admin bypass ⇒ post
490
- * the refusal, return "declined", and the caller dispatches NO model turn — DMs included
491
- * (OPE-267 removed checkCap's DM exemption). Fail-open on any gate error (the helper's own
492
- * console.warn).
493
- *
494
- * The refusal is posted through {@link postOnce}, keyed on (surface, thread root): an ambient
495
- * channel over cap answers ONCE per conversation instead of once per message, while a genuinely
496
- * new thread still gets told why it's being ignored. Fail-open by contract — a dedupe-store
497
- * outage posts anyway.
498
- */
499
- export declare function slackWakeSpendGate(ev: ParsedMessageEvent, p: Partition, threadRootTs: string): Promise<SpendGateDecision>;
500
484
  /**
501
485
  * {@link tenantFenceDeclined} for a door the FRONT route owns — the diverted DM window and the
502
486
  * shortcut ingress (OPE-1644).
@@ -651,7 +635,6 @@ export declare const DM_DRIVER_ADMIT_REASON = "e2e driver \u2014 the DM door adm
651
635
  */
652
636
  export declare function auditDmDriverAdmitted(ev: ParsedMessageEvent, dmKind: "im" | "mpim"): Promise<void>;
653
637
  export declare function liveDeps(send: WakeSend): MessageRouteDeps;
654
- export declare const _engagementWakeMode: (ev: ParsedMessageEvent) => import("@open-everywhere/core/agent/adapter-api.js").SessionMode;
655
638
  /** One wake needle: an id (for logs/attribution) + the pattern that fires it. */
656
639
  export interface WakeTrigger {
657
640
  readonly id: string;
@@ -684,22 +667,6 @@ export interface NameDropInput {
684
667
  * was explicitly added to person-by-person, where name-drop barging feels worst.
685
668
  */
686
669
  export declare function shouldNameDropWake(input: NameDropInput): ReplyDecision;
687
- /**
688
- * Did the built-in name-drop ABSTAIN on this message, as opposed to dropping it for policy?
689
- *
690
- * 🔴 THE WHOLE WAKE-ARM RUNG RESTS ON THIS DISTINCTION (OPE-1367, docs/extending/drop-in-arms.md).
691
- * {@link shouldNameDropWake} answers `deliver: false` for seven different reasons and only ONE of
692
- * them is "I have no opinion": the text does not name the agent. The other six are policy — a DM
693
- * or group DM (the mention path already always-wakes a DM), a bot author, an `app_mention`, a
694
- * message subtype, a domain that never enabled the name-drop wake, and a channel the internal probe
695
- * could not confirm. A consumer's arm may fill the abstention. It may not overturn a policy drop.
696
- *
697
- * 🔴 DERIVED FROM THE BUILT-IN, NEVER RE-LISTED. This asks the built-in itself: with the name
698
- * matched and everything else exactly as it is, would it wake? A hand-kept copy of the
699
- * disqualifiers would go stale the first time somebody adds one to the policy above, and the arm
700
- * would then reach a message the policy had just started dropping.
701
- */
702
- export declare function nameDropAbstained(input: NameDropInput): boolean;
703
670
  /**
704
671
  * The message a name-drop turn receives. A HIGHER bar than the engaged-thread judge:
705
672
  * the agent was never invited into this conversation, so "when in doubt, stay out". The
@@ -854,8 +821,6 @@ export interface NameDropRouteDeps {
854
821
  */
855
822
  export declare function routeNameDropEvent(ev: ParsedMessageEvent, deps: NameDropRouteDeps): Promise<RouteOutcome>;
856
823
  export declare function botDisplayName(): Promise<string | undefined>;
857
- /** Reset the cached display name (tests only). */
858
- export declare function _resetBotDisplayName(): void;
859
824
  /**
860
825
  * Positively confirm a channel is internal (fail-closed, TTL-cached — see
861
826
  * channelInternalAndMeta). Exported because the routine dispatcher
@@ -1027,25 +992,6 @@ export declare function applySlackExternalPolicy(ev: ParsedMessageEvent, p: Part
1027
992
  readonly trust: WakeTrust;
1028
993
  readonly refuted: boolean;
1029
994
  }, route: string): Promise<SlackExternalVerdict>;
1030
- /**
1031
- * Withhold an EXCLUDED author's HYDRATED CONTEXT LINES on the name-drop wake (OPE-525) — the
1032
- * side-channel slot `withholdWakeBodies` cannot fill on its own.
1033
- *
1034
- * 🔴 WHY THE TRANSFORM NEEDS HELP HERE. Its automatic leg reaches an author whose ENVELOPE message
1035
- * it withheld, and reads their id off that message. A name-drop's hydration quotes people who wrote
1036
- * nothing in the envelope at all, so there is no withheld message to read an id from. This resolves
1037
- * the answer for each distinct hydrated sender and hands the transform the sync predicate it takes.
1038
- *
1039
- * 🔴 A POSITIVE REFUTATION ONLY, AND ONLY FOR A HUMAN SENDER. `probe` returning `undefined` (no
1040
- * token, an API error) is NOT a refutation — absence of evidence, and this leg fails OPEN like every
1041
- * other in the plane. A `bot` line carries a bot id, and a machine author is never excluded, so only
1042
- * `senderType: "user"` lines are asked about.
1043
- *
1044
- * COSTS NOTHING ON THE OPT-OUT GRAIN: `taint` returns the wake by reference before any probe runs.
1045
- * On `withhold` it costs one TTL-cached `users.info` per DISTINCT hydrated author, resolved in
1046
- * parallel, and the render budget caps the hydration at ten lines.
1047
- */
1048
- export declare function withholdNameDropContext(nw: NormalizedWake, policy: ExternalPolicy, teamId: string | undefined, probe?: SlackMemberProbe): Promise<NormalizedWake>;
1049
995
  /**
1050
996
  * Re-grade a first-wake BACKSCROLL bundle's per-message trust with the same per-author probe
1051
997
  * (OPE-466). `backscrollTrustResolver` is SYNCHRONOUS and takes the ROOM's internal verdict, so every
@@ -1176,6 +1122,7 @@ export declare function transcriptFromHistory(history: unknown): string | undefi
1176
1122
  export declare function fetchUserProfileNames(userId: string): Promise<{
1177
1123
  name?: string;
1178
1124
  handle?: string;
1125
+ email?: string;
1179
1126
  } | undefined>;
1180
1127
  type RosterEntry = {
1181
1128
  nativeId: string;
@@ -1371,7 +1318,7 @@ export interface SupervisorRouteDeps {
1371
1318
  window?: UnifiedWindowWake;
1372
1319
  }) => Promise<void>;
1373
1320
  /** Append a durable audit row (e.g. `engagement.stop`). Optional; best-effort. */
1374
- readonly audit?: (action: string, detail: Record<string, unknown>) => Promise<void>;
1321
+ readonly audit?: (action: string, detail: AuditDetail) => Promise<void>;
1375
1322
  /**
1376
1323
  * ENGAGE the trigger's thread as a PARTICIPATING surface (task #100 — window-riding stop parity):
1377
1324
  * called ONLY on an ADDRESSED `directMention` so a mention diverted into the window enrolls its
@@ -1433,6 +1380,8 @@ export interface SupervisorRouteDeps {
1433
1380
  * route's own singleWindow + internal facts — a directMention flag on a non-single-window or
1434
1381
  * non-internal wake degrades safely to the plain channel-watch treatment. Unset ⇒ byte-identical.
1435
1382
  */
1383
+ /** The Slack user ids a message mentions (`<@U…>` or `<@U…|name>`), in the order it names them. Pure. */
1384
+ export declare function slackMentionedUserIds(text: string | undefined): string[];
1436
1385
  export declare function routeSupervisorEvent(ev: ParsedMessageEvent, deps: SupervisorRouteDeps, opts?: {
1437
1386
  readonly directMention?: boolean;
1438
1387
  readonly nameDrop?: boolean;
@@ -1690,4 +1639,5 @@ export declare function liveReactionDeps(botIdentity: {
1690
1639
  }, attachSession?: AttachSessionForCancel): SlackReactionRouteDeps;
1691
1640
  /** Production deps for the channel-join route: the shared marker + live Slack confirmation. */
1692
1641
  export declare function liveChannelJoinDeps(send: WakeSend): ChannelJoinRouteDeps;
1642
+ export {};
1693
1643
  //# sourceMappingURL=slack-events.d.ts.map