@opengeni/db 1.0.1 → 3.2.0-canary.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 (271) hide show
  1. package/dist/attached-browser-devices.d.ts +7 -0
  2. package/dist/automations.d.ts +154 -0
  3. package/dist/canonical-human-identities.js +3 -3
  4. package/dist/capability-integrations.d.ts +13 -0
  5. package/dist/child-lifecycle-notices.d.ts +68 -0
  6. package/dist/{chunk-4SR4HKKA.js → chunk-2EH4WRHL.js} +19 -11
  7. package/dist/chunk-2EH4WRHL.js.map +1 -0
  8. package/dist/{chunk-CUPM3FGB.js → chunk-2PRS4J5Q.js} +3 -3
  9. package/dist/chunk-6HMM2R5T.js +390 -0
  10. package/dist/chunk-6HMM2R5T.js.map +1 -0
  11. package/dist/{chunk-ZWREYEWA.js → chunk-AZHW7R5V.js} +56 -11
  12. package/dist/chunk-AZHW7R5V.js.map +1 -0
  13. package/dist/{chunk-LTG3S6ZY.js → chunk-E6CLMKEE.js} +2 -2
  14. package/dist/{chunk-6ZYKCRFO.js → chunk-KRLPEMLH.js} +7591 -4417
  15. package/dist/chunk-KRLPEMLH.js.map +1 -0
  16. package/dist/chunk-NAB6FKFN.js +516 -0
  17. package/dist/chunk-NAB6FKFN.js.map +1 -0
  18. package/dist/{chunk-SK7YYHBI.js → chunk-SIBYBA2D.js} +46 -1
  19. package/dist/chunk-SIBYBA2D.js.map +1 -0
  20. package/dist/chunk-UZNXG44K.js +4508 -0
  21. package/dist/chunk-UZNXG44K.js.map +1 -0
  22. package/dist/codemode-operations.d.ts +1 -6
  23. package/dist/company-brain-context-selection-schema.d.ts +705 -0
  24. package/dist/company-brain-context-selection.d.ts +94 -0
  25. package/dist/company-brain-governed-writes.d.ts +24 -0
  26. package/dist/company-brain.d.ts +55 -0
  27. package/dist/company-profile-agent-admin.d.ts +15 -0
  28. package/dist/company-profile-schema.d.ts +619 -2
  29. package/dist/company-profile.d.ts +9 -4
  30. package/dist/connection-authority.d.ts +95 -0
  31. package/dist/connection-scopes.d.ts +8 -0
  32. package/dist/connection-tenancy-backfill.d.ts +85 -0
  33. package/dist/connection-token-resolver.d.ts +30 -1
  34. package/dist/database.d.ts +23 -4
  35. package/dist/editable-artifact-durable-export.js +2 -2
  36. package/dist/editable-artifacts.d.ts +2 -2
  37. package/dist/editable-artifacts.js +3 -3
  38. package/dist/governed-learning-activation-schema.d.ts +984 -0
  39. package/dist/governed-learning-activation.d.ts +98 -0
  40. package/dist/governed-learning-evaluator-schema.d.ts +633 -0
  41. package/dist/governed-learning-evaluator.d.ts +28 -0
  42. package/dist/index.d.ts +1606 -81
  43. package/dist/index.js +21898 -8147
  44. package/dist/index.js.map +1 -1
  45. package/dist/insights.d.ts +18 -0
  46. package/dist/integration-bindings.d.ts +1 -0
  47. package/dist/integration-facets.d.ts +30 -0
  48. package/dist/interaction-placement-loss.d.ts +22 -0
  49. package/dist/managed-human-provisioning.d.ts +25 -0
  50. package/dist/memory-domain.d.ts +3 -3
  51. package/dist/migrate.d.ts +11 -1
  52. package/dist/migrate.js +1 -1
  53. package/dist/new-session-drafts.d.ts +43 -5
  54. package/dist/organization-membership-backfill.d.ts +174 -0
  55. package/dist/organization-membership-lifecycle.d.ts +162 -0
  56. package/dist/pr-review.d.ts +107 -0
  57. package/dist/preference-registry-schema.d.ts +2 -0
  58. package/dist/preference-registry.d.ts +2 -0
  59. package/dist/provision-roles.js +1 -1
  60. package/dist/runtime-posture.d.ts +29 -8
  61. package/dist/schema.d.ts +24914 -13703
  62. package/dist/schema.js +99 -1
  63. package/dist/scoped-knowledge-schema.d.ts +52 -1
  64. package/dist/session-background-commands.d.ts +125 -0
  65. package/dist/session-background-commands.js +34 -0
  66. package/dist/session-background-commands.js.map +1 -0
  67. package/dist/session-control.d.ts +156 -3
  68. package/dist/session-goal-pacing.d.ts +68 -0
  69. package/dist/session-queue-commands.d.ts +43 -4
  70. package/dist/session-realtime-ledger.d.ts +2 -0
  71. package/dist/session-tenancy.d.ts +71 -1
  72. package/dist/session-tenancy.js +25 -3
  73. package/dist/session-tool-call-settlement.d.ts +9 -4
  74. package/dist/slack-routing-personal-workspace.d.ts +23 -0
  75. package/dist/slack-routing.d.ts +268 -0
  76. package/dist/slack-task-policy-schema.d.ts +34 -0
  77. package/dist/slack-task-policy.d.ts +8 -0
  78. package/dist/slack-user-link-access.d.ts +28 -0
  79. package/dist/task-notes-schema.d.ts +594 -0
  80. package/dist/task-notes.d.ts +39 -0
  81. package/dist/turn-initiator.d.ts +2 -0
  82. package/dist/user-resource-authority.d.ts +109 -0
  83. package/dist/video-generation.js +3 -3
  84. package/dist/workspace-authority.d.ts +81 -0
  85. package/dist/workspace-instruction-policies-schema.d.ts +279 -0
  86. package/dist/workspace-instruction-policies.d.ts +62 -0
  87. package/dist/workspace-learning-policy.d.ts +1 -0
  88. package/dist/workspace-membership-permissions.d.ts +2 -0
  89. package/drizzle/0240_enrollment_connection_authority.sql +39 -0
  90. package/drizzle/0241_atomic_personal_resource_delegation.sql +1000 -0
  91. package/drizzle/0241_enrollment_agent_runtime.sql +70 -0
  92. package/drizzle/0244_slack_app_home_refresh_queue.sql +120 -0
  93. package/drizzle/0245_model_context_contribution_facts.sql +88 -0
  94. package/drizzle/0246_integration_personal_instance_authority.sql +70 -0
  95. package/drizzle/0247_terraform_stacks_provenance_repair.sql +428 -0
  96. package/drizzle/0248_terraform_stacks_component_resolution_fence.sql +83 -0
  97. package/drizzle/0249_personal_resource_delegation_authority_correction.sql +662 -0
  98. package/drizzle/0250_direct_retained_process_owner_liveness.sql +199 -0
  99. package/drizzle/0251_connected_machine_operation_policy.sql +45 -0
  100. package/drizzle/0252_scheduled_personal_resource_delegation.sql +1867 -0
  101. package/drizzle/0253_common_user_resource_authority_lifecycle.sql +1555 -0
  102. package/drizzle/0254_scoped_variable_set_authority.sql +1255 -0
  103. package/drizzle/0255_company_brain_governed_write_proposals.sql +524 -0
  104. package/drizzle/0256_connection_authority_delegation.sql +703 -0
  105. package/drizzle/0257_goal_revision_decisions_and_root_constraints.sql +436 -0
  106. package/drizzle/0258_three_scope_document_knowledge_authority.sql +1273 -0
  107. package/drizzle/0259_company_brain_context_selection_receipts.sql +869 -0
  108. package/drizzle/0260_task_note_knowledge_promotion.sql +820 -0
  109. package/drizzle/0261_preference_knowledge_proposal_actor_binding.sql +471 -0
  110. package/drizzle/0262_scoped_connected_machines_and_rigs.sql +1700 -0
  111. package/drizzle/0263_organization_membership_lifecycle.sql +3284 -0
  112. package/drizzle/0264_connection_authority_runtime_activation.sql +1084 -0
  113. package/drizzle/0266_company_brain_context_receipt_inspection.sql +156 -0
  114. package/drizzle/0268_governed_learning_decision_receipts.sql +825 -0
  115. package/drizzle/0269_governed_learning_activation_controller.sql +1874 -0
  116. package/drizzle/0270_governed_learning_history_inspection.sql +170 -0
  117. package/drizzle/0271_company_brain_retrieval_only_default.sql +524 -0
  118. package/drizzle/0272_human_confirmed_learning_activation.sql +591 -0
  119. package/drizzle/0273_scheduled_variable_set_materialization.sql +268 -0
  120. package/drizzle/0274_human_confirmed_knowledge_review.sql +310 -0
  121. package/drizzle/0275_scheduled_connection_authority.sql +5527 -0
  122. package/drizzle/0276_onboarding_proposal_initiating_human_guc.sql +198 -0
  123. package/drizzle/0277_workspace_writer_authority_attribution.sql +393 -0
  124. package/drizzle/0278_workspace_membership_removal_fencing.sql +1174 -0
  125. package/drizzle/0279_workspace_connection_use_lane.sql +343 -0
  126. package/drizzle/0280_connection_and_variable_set_audit_attribution.sql +773 -0
  127. package/drizzle/0281_viewer_holder_authority_claims.sql +52 -0
  128. package/drizzle/0282_variable_set_session_attach_attribution.sql +178 -0
  129. package/drizzle/0283_editable_spreadsheet_authored_state.sql +82 -0
  130. package/drizzle/0284_truthful_human_confirmed_review_reason.sql +930 -0
  131. package/drizzle/0285_organization_tenancy_inventory.sql +329 -0
  132. package/drizzle/0286_widen_task_note_expiry_ceiling.sql +391 -0
  133. package/drizzle/0287_open_suffix_pending_tool_calls.sql +18 -0
  134. package/drizzle/0288_attached_browser_reenrollment.sql +64 -0
  135. package/drizzle/0289_session_composer_policy_authority.sql +597 -0
  136. package/drizzle/0290_organization_membership_backfill.sql +268 -0
  137. package/drizzle/0291_resource_authority_classification_assertion.sql +371 -0
  138. package/drizzle/0292_truthful_tenancy_inventory_counters.sql +291 -0
  139. package/drizzle/0293_confirm_time_rule_rebaseline.sql +615 -0
  140. package/drizzle/0294_preference_activation_authority.sql +237 -0
  141. package/drizzle/0295_retire_legacy_standing_memory_mode.sql +476 -0
  142. package/drizzle/0296_force_rls_backfill_noop_repair.sql +215 -0
  143. package/drizzle/0297_session_ownership_classification_and_backfill.sql +752 -0
  144. package/drizzle/0298_organization_tenancy_parity.sql +609 -0
  145. package/drizzle/0299_organization_membership_lock_order.sql +291 -0
  146. package/drizzle/0300_tenancy_backfill_ledger.sql +459 -0
  147. package/drizzle/0301_session_snapshot_and_pin_visibility.sql +181 -0
  148. package/drizzle/0302_personal_workspace_session_ownership.sql +303 -0
  149. package/drizzle/0303_session_tenancy_product_activation.sql +919 -0
  150. package/drizzle/0304_personal_workspace_private_session_reads.sql +97 -0
  151. package/drizzle/0305_personal_resource_grant_management.sql +584 -0
  152. package/drizzle/0306_atomic_personal_resource_attachments.sql +1374 -0
  153. package/drizzle/0307_session_attention_state.sql +51 -0
  154. package/drizzle/0308_session_archives.sql +35 -0
  155. package/drizzle/0309_channel_project_pins.sql +6 -0
  156. package/drizzle/0310_channel_project_order.sql +27 -0
  157. package/drizzle/0311_company_scope_and_private_session_create.sql +656 -0
  158. package/drizzle/0312_quiescent_session_tree_deletion.sql +39 -0
  159. package/drizzle/0313_private_child_session_authority.sql +365 -0
  160. package/drizzle/0314_unregistered_organization_invitations.sql +606 -0
  161. package/drizzle/0315_personal_github_repository_selection.sql +624 -0
  162. package/drizzle/0316_human_confirmed_activation_resumed_generation.sql +869 -0
  163. package/drizzle/0317_session_goal_continuation_hold.sql +64 -0
  164. package/drizzle/0318_session_turn_startup_milestones.sql +115 -0
  165. package/drizzle/0319_event_triggered_automations.sql +254 -0
  166. package/drizzle/0320_pr_review_pack.sql +113 -0
  167. package/drizzle/0321_slack_bot_environment_display_name.sql +15 -0
  168. package/drizzle/0322_session_turns_unclaimed_prompt_trigger_index.sql +5 -0
  169. package/drizzle/0323_organization_private_session_enablement.sql +489 -0
  170. package/drizzle/0324_human_confirmed_company_profile_agent_admin.sql +856 -0
  171. package/drizzle/0325_child_lifecycle_notices.sql +44 -0
  172. package/drizzle/0326_interaction_operation_error_codes.sql +62 -0
  173. package/drizzle/0327_slack_first_task_hint.sql +29 -0
  174. package/drizzle/0328_session_background_commands.sql +590 -0
  175. package/drizzle/0329_slack_orchestration_delivery_events.sql +91 -0
  176. package/drizzle/0330_api_key_descriptions.sql +20 -0
  177. package/drizzle/0331_managed_organization_creation.sql +163 -0
  178. package/drizzle/0332_organization_shared_workspace_control_plane.sql +539 -0
  179. package/drizzle/0333_session_turn_prompt_routing.sql +45 -0
  180. package/drizzle/0334_connected_machine_workspace_root.sql +99 -0
  181. package/drizzle/0335_slack_workspace_routing.sql +460 -0
  182. package/drizzle/0336_atomic_session_fork_visibility.sql +667 -0
  183. package/drizzle/0337_slack_routed_action_handles.sql +189 -0
  184. package/drizzle/0338_atomic_connected_machine_attachments.sql +410 -0
  185. package/drizzle/0339_document_authority_reclassification.sql +1153 -0
  186. package/drizzle/0340_tenancy_backfill_activation_evidence.sql +1347 -0
  187. package/drizzle/0341_slack_routing_probe_organization_fence.sql +109 -0
  188. package/drizzle/0342_slack_route_prompt_single_pending.sql +32 -0
  189. package/drizzle/0343_personal_document_force_rls_lock_repair.sql +146 -0
  190. package/drizzle/0344_private_session_visibility_transition_gate.sql +85 -0
  191. package/drizzle/0345_tenant_scoped_session_tenancy_fence.sql +2839 -0
  192. package/drizzle/0346_document_migration_audit_surface.sql +454 -0
  193. package/drizzle/0347_connection_authority_convergence_evidence.sql +396 -0
  194. package/package.json +10 -6
  195. package/src/attached-browser-devices.ts +233 -5
  196. package/src/automations.ts +911 -0
  197. package/src/browser-sessions.ts +10 -0
  198. package/src/capability-integrations.ts +175 -1
  199. package/src/child-lifecycle-notices.ts +241 -0
  200. package/src/codemode-operations.ts +1 -35
  201. package/src/company-brain-context-selection-schema.ts +100 -0
  202. package/src/company-brain-context-selection.ts +359 -0
  203. package/src/company-brain-governed-writes.ts +1170 -0
  204. package/src/company-brain.ts +309 -0
  205. package/src/company-profile-agent-admin.ts +225 -0
  206. package/src/company-profile-schema.ts +121 -1
  207. package/src/company-profile.ts +21 -0
  208. package/src/computer-sessions.ts +10 -1
  209. package/src/connection-authority.ts +290 -0
  210. package/src/connection-scopes.ts +20 -0
  211. package/src/connection-tenancy-backfill.ts +167 -0
  212. package/src/connection-token-resolver.ts +263 -31
  213. package/src/database.ts +87 -2
  214. package/src/editable-artifacts-schema.ts +10 -5
  215. package/src/editable-artifacts.ts +21 -11
  216. package/src/governed-learning-activation-schema.ts +121 -0
  217. package/src/governed-learning-activation.ts +588 -0
  218. package/src/governed-learning-evaluator-schema.ts +72 -0
  219. package/src/governed-learning-evaluator.ts +217 -0
  220. package/src/index.ts +11676 -1550
  221. package/src/insights.ts +107 -0
  222. package/src/integration-bindings.ts +88 -6
  223. package/src/integration-facets.ts +287 -84
  224. package/src/interaction-placement-loss.ts +234 -0
  225. package/src/managed-human-provisioning.ts +116 -0
  226. package/src/memory-domain.ts +27 -32
  227. package/src/migrate.ts +77 -1
  228. package/src/new-session-drafts.ts +229 -35
  229. package/src/organization-membership-backfill.ts +735 -0
  230. package/src/organization-membership-lifecycle.ts +995 -0
  231. package/src/pr-review.ts +890 -0
  232. package/src/preference-registry.ts +31 -1
  233. package/src/provision-roles.ts +905 -6
  234. package/src/runtime-posture-cli.ts +2 -0
  235. package/src/runtime-posture.ts +1317 -72
  236. package/src/schema.ts +3316 -428
  237. package/src/scoped-knowledge-schema.ts +16 -8
  238. package/src/scoped-knowledge.ts +1 -1
  239. package/src/session-background-commands.ts +759 -0
  240. package/src/session-control.ts +640 -74
  241. package/src/session-goal-pacing.ts +126 -0
  242. package/src/session-queue-commands.ts +441 -85
  243. package/src/session-realtime-context.ts +4 -6
  244. package/src/session-realtime-ledger.ts +28 -14
  245. package/src/session-realtime-mirror.ts +1 -1
  246. package/src/session-tenancy.ts +410 -49
  247. package/src/session-tool-call-settlement.ts +38 -29
  248. package/src/slack-routing-personal-workspace.ts +67 -0
  249. package/src/slack-routing.ts +867 -0
  250. package/src/slack-task-policy-schema.ts +5 -0
  251. package/src/slack-task-policy.ts +18 -0
  252. package/src/slack-user-link-access.ts +138 -11
  253. package/src/task-notes-schema.ts +74 -0
  254. package/src/task-notes.ts +124 -2
  255. package/src/turn-initiator.ts +8 -0
  256. package/src/user-resource-authority.ts +377 -0
  257. package/src/workspace-authority.ts +160 -0
  258. package/src/workspace-instruction-policies-schema.ts +53 -1
  259. package/src/workspace-instruction-policies.ts +528 -77
  260. package/src/workspace-learning-policy.ts +21 -5
  261. package/src/workspace-membership-permissions.ts +9 -0
  262. package/dist/chunk-4SR4HKKA.js.map +0 -1
  263. package/dist/chunk-6ZYKCRFO.js.map +0 -1
  264. package/dist/chunk-NXAFLCQX.js +0 -2468
  265. package/dist/chunk-NXAFLCQX.js.map +0 -1
  266. package/dist/chunk-SK7YYHBI.js.map +0 -1
  267. package/dist/chunk-WD5ROSLL.js +0 -117
  268. package/dist/chunk-WD5ROSLL.js.map +0 -1
  269. package/dist/chunk-ZWREYEWA.js.map +0 -1
  270. /package/dist/{chunk-CUPM3FGB.js.map → chunk-2PRS4J5Q.js.map} +0 -0
  271. /package/dist/{chunk-LTG3S6ZY.js.map → chunk-E6CLMKEE.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import type { SessionEvent } from "@opengeni/contracts";
2
- import { boundModelToolOutputItem } from "@opengeni/codex";
3
- import { and, asc, eq, sql } from "drizzle-orm";
2
+ import { canonicalizePersistedHistoryItem, omitOutputOnlyHistoryItemFields } from "@opengeni/codex";
3
+ import { and, asc, eq, inArray, sql } from "drizzle-orm";
4
4
  import type { Database } from "./database";
5
5
  import { fromPostgresLosslessJson, LOSSLESS_CONTENT_CODEC_VERSION } from "./lossless-json";
6
6
  import * as schema from "./schema";
@@ -85,6 +85,8 @@ export type ClosePendingSessionToolCallsInput = {
85
85
  reason: string;
86
86
  sequence: number;
87
87
  now: Date;
88
+ turnAssociation?: "current" | null;
89
+ preserveInterruptionRows?: boolean;
88
90
  };
89
91
 
90
92
  function mapEvent(row: typeof schema.sessionEvents.$inferSelect): SessionEvent {
@@ -107,10 +109,13 @@ function mapEvent(row: typeof schema.sessionEvents.$inferSelect): SessionEvent {
107
109
  }
108
110
 
109
111
  /**
110
- * Close every unresolved raw tool call for a logical turn while its owning
111
- * session/turn locks are held. Durable results win; otherwise the model gets an
112
- * explicit interrupted/outcome-unknown result for protocols that can represent
113
- * one. Repeated settlement is an exact no-op after ledger deletion.
112
+ * Close raw tool calls for a logical turn while its owning session/turn locks
113
+ * are held. Recoverable transitions preserve interruption rows because those
114
+ * rows are the exact open-suffix resume authority for a replacement attempt;
115
+ * ordinary in-flight rows still receive durable outcome-unknown settlement.
116
+ * Terminal and superseding transitions close every row. Durable results win;
117
+ * repeated settlement is an exact no-op after the selected ledger rows are
118
+ * deleted.
114
119
  */
115
120
  export async function closePendingSessionToolCallsInTransaction(
116
121
  tx: Database,
@@ -128,18 +133,20 @@ export async function closePendingSessionToolCallsInTransaction(
128
133
  )
129
134
  .orderBy(asc(schema.sessionPendingToolCalls.createdAt), asc(schema.sessionPendingToolCalls.id))
130
135
  .for("update");
131
- const pending = pendingRows.map((row) => ({
132
- ...row,
133
- callItem: fromPostgresLosslessJson(row.callItem, row.callItemCodecVersion),
134
- resultItem:
135
- row.resultItem === null
136
- ? null
137
- : fromPostgresLosslessJson(row.resultItem, row.resultItemCodecVersion),
138
- eventOutput:
139
- row.eventOutput === null
140
- ? null
141
- : fromPostgresLosslessJson(row.eventOutput, row.eventOutputCodecVersion),
142
- }));
136
+ const pending = pendingRows
137
+ .filter((row) => !(input.preserveInterruptionRows && row.interruptionKind !== null))
138
+ .map((row) => ({
139
+ ...row,
140
+ callItem: fromPostgresLosslessJson(row.callItem, row.callItemCodecVersion),
141
+ resultItem:
142
+ row.resultItem === null
143
+ ? null
144
+ : fromPostgresLosslessJson(row.resultItem, row.resultItemCodecVersion),
145
+ eventOutput:
146
+ row.eventOutput === null
147
+ ? null
148
+ : fromPostgresLosslessJson(row.eventOutput, row.eventOutputCodecVersion),
149
+ }));
143
150
  if (pending.length === 0) return { sequence: input.sequence, events: [], closed: 0 };
144
151
 
145
152
  const history = await tx
@@ -250,7 +257,7 @@ export async function closePendingSessionToolCallsInTransaction(
250
257
  sessionId: input.sessionId,
251
258
  turnId: input.turnId,
252
259
  position: nextPosition++,
253
- item: resolution.call.callItem,
260
+ item: omitOutputOnlyHistoryItemFields(resolution.call.callItem),
254
261
  itemCodecVersion: LOSSLESS_CONTENT_CODEC_VERSION,
255
262
  active: true,
256
263
  });
@@ -274,7 +281,7 @@ export async function closePendingSessionToolCallsInTransaction(
274
281
  sessionId: input.sessionId,
275
282
  turnId: input.turnId,
276
283
  position: nextPosition++,
277
- item: boundModelToolOutputItem(
284
+ item: canonicalizePersistedHistoryItem(
278
285
  resolution.result,
279
286
  resolution.call.modelToolOutputTruncationTokens ?? undefined,
280
287
  ),
@@ -297,7 +304,7 @@ export async function closePendingSessionToolCallsInTransaction(
297
304
  turnId: input.turnId,
298
305
  turnGeneration: resolution.call.executionGeneration,
299
306
  turnAttemptId: resolution.call.attemptId,
300
- turnAssociation: "current",
307
+ turnAssociation: input.turnAssociation === undefined ? "current" : input.turnAssociation,
301
308
  payload: {
302
309
  id: resolution.call.callId,
303
310
  output: resolution.interrupted
@@ -341,14 +348,16 @@ export async function closePendingSessionToolCallsInTransaction(
341
348
  reason: input.reason,
342
349
  now: input.now,
343
350
  });
344
- await tx
345
- .delete(schema.sessionPendingToolCalls)
346
- .where(
347
- and(
348
- eq(schema.sessionPendingToolCalls.workspaceId, input.workspaceId),
349
- eq(schema.sessionPendingToolCalls.sessionId, input.sessionId),
350
- eq(schema.sessionPendingToolCalls.turnId, input.turnId),
351
+ await tx.delete(schema.sessionPendingToolCalls).where(
352
+ and(
353
+ eq(schema.sessionPendingToolCalls.workspaceId, input.workspaceId),
354
+ eq(schema.sessionPendingToolCalls.sessionId, input.sessionId),
355
+ eq(schema.sessionPendingToolCalls.turnId, input.turnId),
356
+ inArray(
357
+ schema.sessionPendingToolCalls.id,
358
+ pending.map((call) => call.id),
351
359
  ),
352
- );
360
+ ),
361
+ );
353
362
  return { sequence, events: inserted.map(mapEvent), closed: pending.length };
354
363
  }
@@ -0,0 +1,67 @@
1
+ // The personal-workspace pointer, in its own leaf module.
2
+ //
3
+ // Both the Slack routing resolvers and the Slack access-request path need it,
4
+ // and this keeps that from becoming an import cycle between them.
5
+ import { sql } from "drizzle-orm";
6
+
7
+ import { type Database } from "./database";
8
+ import { listSelfOrganizationMemberships } from "./organization-membership-lifecycle";
9
+ import { rlsSubjectIdOrEmpty } from "./workspace-authority";
10
+
11
+ /**
12
+ * The subject's own personal workspace in one organization, or null.
13
+ *
14
+ * Only an `active` membership counts, and only that membership's own
15
+ * `personalWorkspaceId` pointer is read - never a default workspace, a
16
+ * `created_by`, or current access.
17
+ *
18
+ * Non-`user:` subjects (API keys, delegated service principals, configured and
19
+ * local principals) can never own an organization membership, so they
20
+ * short-circuit rather than tripping `list_self_organization_memberships`'
21
+ * `42501` guard.
22
+ *
23
+ * ORACLE, NOT AN AUTHORIZATION. This answers "which workspace is this named
24
+ * subject's own" for whatever subject it is handed; it does not establish that
25
+ * the caller IS that subject. Pass only a subject authenticated out of band -
26
+ * for Slack, one named by a durable `slack_bot_user_links` row. Never pass a
27
+ * subject taken from a request payload.
28
+ */
29
+ export async function namedSubjectPersonalWorkspaceId(
30
+ db: Database,
31
+ input: { accountId: string; subjectId: string },
32
+ ): Promise<string | null> {
33
+ if (!input.subjectId.startsWith("user:")) return null;
34
+ // `listSelfOrganizationMemberships` opens its own scope and sets
35
+ // `opengeni.subject_id` to the probed subject. Under drizzle a nested
36
+ // transaction is a SAVEPOINT, and releasing a savepoint does NOT undo a
37
+ // transaction-local `set_config`, so without this the probed subject would
38
+ // leak out and silently re-scope the rest of a caller-owned transaction.
39
+ // `namedSubjectHasLiveWorkspaceAuthority` guards the same hazard the same
40
+ // way; empty string is the canonical "unset" because `current_subject_id()`
41
+ // is `nullif(current_setting(...), '')`.
42
+ const priorSubjectId = await rlsSubjectIdOrEmpty(db);
43
+ let completed = false;
44
+ try {
45
+ const memberships = await listSelfOrganizationMemberships(db, input.subjectId);
46
+ const membership = memberships.find(
47
+ (candidate) =>
48
+ candidate.status === "active" &&
49
+ candidate.organizationId === input.accountId &&
50
+ candidate.personalWorkspaceId !== null,
51
+ );
52
+ completed = true;
53
+ return membership?.personalWorkspaceId ?? null;
54
+ } finally {
55
+ const restore = db.execute(
56
+ sql`select set_config('opengeni.subject_id', ${priorSubjectId}, true)`,
57
+ );
58
+ if (completed) {
59
+ await restore;
60
+ } else {
61
+ // A failed statement can leave a caller-owned transaction aborted.
62
+ // Preserve the original diagnostic rather than replacing it with the
63
+ // restore's `25P02`.
64
+ await restore.catch(() => undefined);
65
+ }
66
+ }
67
+ }