@opengeni/db 0.27.7 → 0.27.9

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 (61) hide show
  1. package/dist/{chunk-IHPCI4GV.js → chunk-2JFRTKTG.js} +1 -1
  2. package/dist/chunk-2JFRTKTG.js.map +1 -0
  3. package/dist/{chunk-EX7CDSGH.js → chunk-NX2JNJJP.js} +13 -4
  4. package/dist/chunk-NX2JNJJP.js.map +1 -0
  5. package/dist/codex-token-resolver.d.ts +50 -8
  6. package/dist/connection-token-resolver.d.ts +45 -7
  7. package/dist/database.d.ts +137 -0
  8. package/dist/index.d.ts +25 -154
  9. package/dist/index.js +2796 -2634
  10. package/dist/index.js.map +1 -1
  11. package/dist/insights.d.ts +1 -1
  12. package/dist/memory-governance.d.ts +1 -1
  13. package/dist/new-session-drafts.d.ts +1 -1
  14. package/dist/preference-registry.d.ts +1 -1
  15. package/dist/provision-roles.d.ts +1 -1
  16. package/dist/provision-roles.js +1 -1
  17. package/dist/runtime-posture.d.ts +1 -1
  18. package/dist/schema.d.ts +44 -0
  19. package/dist/schema.js +1 -1
  20. package/dist/scoped-knowledge.d.ts +1 -1
  21. package/dist/session-control.d.ts +2 -1
  22. package/dist/session-queue-commands.d.ts +1 -1
  23. package/dist/session-realtime-context.d.ts +1 -1
  24. package/dist/session-realtime-ledger.d.ts +1 -1
  25. package/dist/session-realtime-mirror.d.ts +1 -1
  26. package/dist/session-realtime-state.d.ts +1 -1
  27. package/dist/session-realtime-terminal.d.ts +1 -1
  28. package/dist/session-realtime.d.ts +1 -1
  29. package/dist/session-tool-call-settlement.d.ts +1 -1
  30. package/dist/turn-initiator.d.ts +1 -1
  31. package/dist/workspace-artifacts.d.ts +1 -1
  32. package/dist/workspace-instruction-policies.d.ts +1 -1
  33. package/drizzle/0170_session_control_wake_revision.sql +133 -0
  34. package/drizzle/0171_social_connection_subject_ownership.sql +53 -0
  35. package/package.json +3 -3
  36. package/src/codex-token-resolver.ts +102 -49
  37. package/src/connection-token-resolver.ts +67 -26
  38. package/src/database.ts +393 -0
  39. package/src/index.ts +439 -516
  40. package/src/insights.ts +2 -2
  41. package/src/memory-governance.ts +2 -2
  42. package/src/new-session-drafts.ts +1 -1
  43. package/src/preference-registry.ts +2 -2
  44. package/src/provision-roles.ts +1 -1
  45. package/src/runtime-posture.ts +1 -1
  46. package/src/schema.ts +16 -3
  47. package/src/scoped-knowledge.ts +2 -2
  48. package/src/session-control.ts +12 -5
  49. package/src/session-queue-commands.ts +4 -1
  50. package/src/session-realtime-context.ts +1 -1
  51. package/src/session-realtime-ledger.ts +1 -1
  52. package/src/session-realtime-mirror.ts +1 -1
  53. package/src/session-realtime-state.ts +1 -1
  54. package/src/session-realtime-terminal.ts +1 -1
  55. package/src/session-realtime.ts +1 -1
  56. package/src/session-tool-call-settlement.ts +1 -1
  57. package/src/turn-initiator.ts +1 -1
  58. package/src/workspace-artifacts.ts +2 -2
  59. package/src/workspace-instruction-policies.ts +2 -2
  60. package/dist/chunk-EX7CDSGH.js.map +0 -1
  61. package/dist/chunk-IHPCI4GV.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import type { Database } from "./index";
1
+ import type { Database } from "./database";
2
2
  export type InsightsTimeWindow = {
3
3
  since: Date;
4
4
  until: Date;
@@ -1,4 +1,4 @@
1
- import type { Database } from "./index";
1
+ import type { Database } from "./database";
2
2
  import { type MemoryOperationPlanInput, type MemoryRevertPlanInput } from "./memory-domain";
3
3
  export declare class MemoryGovernanceAuthorityError extends Error {
4
4
  readonly name = "MemoryGovernanceAuthorityError";
@@ -1,5 +1,5 @@
1
1
  import type { NewSessionDraftOptions, LatencyMode, ReasoningEffort, ResourceRef, ToolRef } from "@opengeni/contracts";
2
- import type { Database } from "./index";
2
+ import type { Database } from "./database";
3
3
  import * as schema from "./schema";
4
4
  export type NewSessionDraftRow = typeof schema.newSessionDrafts.$inferSelect;
5
5
  export declare class NewSessionDraftConflictError extends Error {
@@ -1,5 +1,5 @@
1
1
  import { PreferenceRegistryDescriptor, type CreatePreferenceRegistryProposalRequest, type PreferenceRegistryConflictStrategy, type PreferenceRegistryScope, type PreferenceRegistryStatus } from "@opengeni/contracts";
2
- import type { Database } from "./index";
2
+ import type { Database } from "./database";
3
3
  export declare class PreferenceRegistryNotFoundError extends Error {
4
4
  readonly name = "PreferenceRegistryNotFoundError";
5
5
  }
@@ -1,4 +1,4 @@
1
- import type { RlsStrategy } from "./index";
1
+ import type { RlsStrategy } from "./database";
2
2
  export type ProvisionResult = {
3
3
  appRole: string | null;
4
4
  hostExportRole: string | null;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  provisionRoles
3
- } from "./chunk-IHPCI4GV.js";
3
+ } from "./chunk-2JFRTKTG.js";
4
4
  import "./chunk-PZ5AY32C.js";
5
5
  export {
6
6
  provisionRoles
@@ -1,4 +1,4 @@
1
- import type { Database, RlsStrategy } from "./index";
1
+ import type { Database, RlsStrategy } from "./database";
2
2
  /**
3
3
  * The complete standalone tenant-table contract. Adding or removing a
4
4
  * FORCE-RLS table is an architectural change: update this list in the same
package/dist/schema.d.ts CHANGED
@@ -6930,6 +6930,7 @@ export declare const sessions: import("drizzle-orm/pg-core").PgTableWithColumns<
6930
6930
  ownerSubjectId: string;
6931
6931
  providerDomain: string;
6932
6932
  kind?: "api_key" | "app_install" | "delegated" | "oauth2" | undefined;
6933
+ connectionType?: "mcp" | "social" | undefined;
6933
6934
  }[];
6934
6935
  driverParam: unknown;
6935
6936
  notNull: true;
@@ -6948,6 +6949,7 @@ export declare const sessions: import("drizzle-orm/pg-core").PgTableWithColumns<
6948
6949
  ownerSubjectId: string;
6949
6950
  providerDomain: string;
6950
6951
  kind?: "api_key" | "app_install" | "delegated" | "oauth2" | undefined;
6952
+ connectionType?: "mcp" | "social" | undefined;
6951
6953
  }[];
6952
6954
  }>;
6953
6955
  toolPolicy: import("drizzle-orm/pg-core").PgColumn<{
@@ -11958,6 +11960,7 @@ export declare const sessionTurns: import("drizzle-orm/pg-core").PgTableWithColu
11958
11960
  ownerSubjectId: string;
11959
11961
  providerDomain: string;
11960
11962
  kind?: "api_key" | "app_install" | "delegated" | "oauth2" | undefined;
11963
+ connectionType?: "mcp" | "social" | undefined;
11961
11964
  }[];
11962
11965
  driverParam: unknown;
11963
11966
  notNull: true;
@@ -11976,6 +11979,7 @@ export declare const sessionTurns: import("drizzle-orm/pg-core").PgTableWithColu
11976
11979
  ownerSubjectId: string;
11977
11980
  providerDomain: string;
11978
11981
  kind?: "api_key" | "app_install" | "delegated" | "oauth2" | undefined;
11982
+ connectionType?: "mcp" | "social" | undefined;
11979
11983
  }[];
11980
11984
  }>;
11981
11985
  cancelledBy: import("drizzle-orm/pg-core").PgColumn<{
@@ -14751,6 +14755,7 @@ export declare const sessionSystemUpdates: import("drizzle-orm/pg-core").PgTable
14751
14755
  ownerSubjectId: string;
14752
14756
  providerDomain: string;
14753
14757
  kind?: "api_key" | "app_install" | "delegated" | "oauth2" | undefined;
14758
+ connectionType?: "mcp" | "social" | undefined;
14754
14759
  }[];
14755
14760
  driverParam: unknown;
14756
14761
  notNull: true;
@@ -14769,6 +14774,7 @@ export declare const sessionSystemUpdates: import("drizzle-orm/pg-core").PgTable
14769
14774
  ownerSubjectId: string;
14770
14775
  providerDomain: string;
14771
14776
  kind?: "api_key" | "app_install" | "delegated" | "oauth2" | undefined;
14777
+ connectionType?: "mcp" | "social" | undefined;
14772
14778
  }[];
14773
14779
  }>;
14774
14780
  state: import("drizzle-orm/pg-core").PgColumn<{
@@ -15088,6 +15094,7 @@ export declare const sessionSystemUpdateOutbox: import("drizzle-orm/pg-core").Pg
15088
15094
  ownerSubjectId: string;
15089
15095
  providerDomain: string;
15090
15096
  kind?: "api_key" | "app_install" | "delegated" | "oauth2" | undefined;
15097
+ connectionType?: "mcp" | "social" | undefined;
15091
15098
  }[];
15092
15099
  driverParam: unknown;
15093
15100
  notNull: true;
@@ -15106,6 +15113,7 @@ export declare const sessionSystemUpdateOutbox: import("drizzle-orm/pg-core").Pg
15106
15113
  ownerSubjectId: string;
15107
15114
  providerDomain: string;
15108
15115
  kind?: "api_key" | "app_install" | "delegated" | "oauth2" | undefined;
15116
+ connectionType?: "mcp" | "social" | undefined;
15109
15117
  }[];
15110
15118
  }>;
15111
15119
  status: import("drizzle-orm/pg-core").PgColumn<{
@@ -15342,6 +15350,23 @@ export declare const sessionWorkflowWakeOutbox: import("drizzle-orm/pg-core").Pg
15342
15350
  identity: undefined;
15343
15351
  generated: undefined;
15344
15352
  }, {}, {}>;
15353
+ controlRevision: import("drizzle-orm/pg-core").PgColumn<{
15354
+ name: "control_revision";
15355
+ tableName: "session_workflow_wake_outbox";
15356
+ dataType: "number";
15357
+ columnType: "PgBigInt53";
15358
+ data: number;
15359
+ driverParam: string | number;
15360
+ notNull: true;
15361
+ hasDefault: true;
15362
+ isPrimaryKey: false;
15363
+ isAutoincrement: false;
15364
+ hasRuntimeDefault: false;
15365
+ enumValues: undefined;
15366
+ baseColumn: never;
15367
+ identity: undefined;
15368
+ generated: undefined;
15369
+ }, {}, {}>;
15345
15370
  reason: import("drizzle-orm/pg-core").PgColumn<{
15346
15371
  name: "reason";
15347
15372
  tableName: "session_workflow_wake_outbox";
@@ -22703,6 +22728,7 @@ export declare const scheduledTasks: import("drizzle-orm/pg-core").PgTableWithCo
22703
22728
  ownerSubjectId: string;
22704
22729
  providerDomain: string;
22705
22730
  kind?: "api_key" | "app_install" | "delegated" | "oauth2" | undefined;
22731
+ connectionType?: "mcp" | "social" | undefined;
22706
22732
  }[];
22707
22733
  driverParam: unknown;
22708
22734
  notNull: true;
@@ -22721,6 +22747,7 @@ export declare const scheduledTasks: import("drizzle-orm/pg-core").PgTableWithCo
22721
22747
  ownerSubjectId: string;
22722
22748
  providerDomain: string;
22723
22749
  kind?: "api_key" | "app_install" | "delegated" | "oauth2" | undefined;
22750
+ connectionType?: "mcp" | "social" | undefined;
22724
22751
  }[];
22725
22752
  }>;
22726
22753
  reusableSessionId: import("drizzle-orm/pg-core").PgColumn<{
@@ -27159,6 +27186,23 @@ export declare const socialConnections: import("drizzle-orm/pg-core").PgTableWit
27159
27186
  identity: undefined;
27160
27187
  generated: undefined;
27161
27188
  }, {}, {}>;
27189
+ subjectId: import("drizzle-orm/pg-core").PgColumn<{
27190
+ name: "subject_id";
27191
+ tableName: "social_connections";
27192
+ dataType: "string";
27193
+ columnType: "PgText";
27194
+ data: string;
27195
+ driverParam: string;
27196
+ notNull: false;
27197
+ hasDefault: false;
27198
+ isPrimaryKey: false;
27199
+ isAutoincrement: false;
27200
+ hasRuntimeDefault: false;
27201
+ enumValues: [string, ...string[]];
27202
+ baseColumn: never;
27203
+ identity: undefined;
27204
+ generated: undefined;
27205
+ }, {}, {}>;
27162
27206
  provider: import("drizzle-orm/pg-core").PgColumn<{
27163
27207
  name: "provider";
27164
27208
  tableName: "social_connections";
package/dist/schema.js CHANGED
@@ -139,7 +139,7 @@ import {
139
139
  workspaceVariableSetVariables,
140
140
  workspaceVariableSets,
141
141
  workspaces
142
- } from "./chunk-EX7CDSGH.js";
142
+ } from "./chunk-NX2JNJJP.js";
143
143
  import "./chunk-PZ5AY32C.js";
144
144
  export {
145
145
  agentRunStates,
@@ -1,5 +1,5 @@
1
1
  import type { EligibleKnowledgeClaim, KnowledgeChangeProposalRecord, KnowledgeClaimEvidencePolarity, KnowledgeClaimOrigin, KnowledgeClaimRecord, KnowledgeClaimRelationType, KnowledgeClaimReviewState, KnowledgeDocumentVersionRecord, KnowledgeFactObjectKind, KnowledgeFactRecord, KnowledgeLifecycleEventType, KnowledgeLifecycleState, KnowledgeProviderRecord, KnowledgeSourceAclVersionRecord, KnowledgeSourceObjectRecord, KnowledgeSourceRecord, KnowledgeSyncRunRecord, ScopedKnowledgeActor, ScopedKnowledgeScope } from "@opengeni/contracts";
2
- import type { Database } from "./index";
2
+ import type { Database } from "./database";
3
3
  type KnowledgeWriteContext = {
4
4
  accountId: string;
5
5
  workspaceId: string;
@@ -1,5 +1,5 @@
1
1
  import { type SessionMcpApprovalPolicy, type TurnInitiatorContext } from "@opengeni/contracts";
2
- import type { Database } from "./index";
2
+ import type { Database } from "./database";
3
3
  import * as schema from "./schema";
4
4
  export declare const SESSION_ANCESTRY_LIMIT = 10000;
5
5
  export type WorkspaceControlLockMode = "none" | "share" | "update";
@@ -259,6 +259,7 @@ export declare function registerSessionWorkflowWakeInTransaction(db: Database, i
259
259
  sessionId: string;
260
260
  temporalWorkflowId: string;
261
261
  reason: string;
262
+ controlRequested?: boolean;
262
263
  }): Promise<number>;
263
264
  /**
264
265
  * Internal producers share one outstanding session-level receipt. While a wake
@@ -1,5 +1,5 @@
1
1
  import { ResourceRef, type McpPersonalConnectionDelegation, type LatencyMode, type ReasoningEffort, type TurnExecutionPolicyV1 } from "@opengeni/contracts";
2
- import type { Database } from "./index";
2
+ import type { Database } from "./database";
3
3
  import { type SessionCommandActor, type SessionCommandReceiptRow } from "./session-control";
4
4
  import * as schema from "./schema";
5
5
  export type QueueCommandConflictCode = "QUEUE_VERSION_CHANGED" | "QUEUE_PROMPT_STARTED" | "QUEUE_ANCHOR_CHANGED" | "PROMPT_CHANGED" | "DRAFT_CHANGED" | "DRAFT_NOT_EMPTY" | "EDIT_SOURCE_CHANGED";
@@ -1,4 +1,4 @@
1
- import type { Database } from "./index";
1
+ import type { Database } from "./database";
2
2
  export declare const SESSION_REALTIME_CONTEXT_MAX_BYTES = 65536;
3
3
  export declare const SESSION_REALTIME_TAIL_SOURCE = "transcript_tail_flush";
4
4
  export declare const SESSION_REALTIME_TAIL_INSTRUCTION = "The user just ended the realtime voice session but remains reachable by text. Ending voice changes only the communication mode; it does not stop, pause, or complete existing work. Treat the remaining transcript tail as additional context. If work was already underway, continue it from the current state. Change or stop that work only if the user explicitly requested it. If nothing was underway and the transcript contains no unhandled request, acknowledge briefly; otherwise handle any unhandled request.";
@@ -1,5 +1,5 @@
1
1
  import { type SessionRealtimeMode } from "@opengeni/contracts";
2
- import type { Database } from "./index";
2
+ import type { Database } from "./database";
3
3
  import { type AssertSessionRealtimeOwnerInput } from "./session-realtime";
4
4
  export declare const SESSION_REALTIME_LEDGER_MAX_BATCH = 64;
5
5
  export declare const SESSION_REALTIME_LEDGER_MAX_TEXT_BYTES = 131072;
@@ -1,5 +1,5 @@
1
1
  import type { HumanInputQuestion, HumanInputResponse } from "@opengeni/contracts";
2
- import type { Database } from "./index";
2
+ import type { Database } from "./database";
3
3
  import * as schema from "./schema";
4
4
  export type SessionRealtimeMirrorChannel = "speakable" | "commentary" | null;
5
5
  export type MirrorSessionRealtimeContextInput = {
@@ -1,2 +1,2 @@
1
- import type { Database } from "./index";
1
+ import type { Database } from "./database";
2
2
  export declare function sessionRealtimeIsActiveInTransaction(db: Database, workspaceId: string, sessionId: string, now?: Date): Promise<boolean>;
@@ -1,4 +1,4 @@
1
- import type { Database } from "./index";
1
+ import type { Database } from "./database";
2
2
  export type ProjectSessionRealtimeDelegationTerminalInput = {
3
3
  accountId: string;
4
4
  workspaceId: string;
@@ -1,5 +1,5 @@
1
1
  import type { SessionRealtimeEndReason, SessionRealtimeMode, SessionRealtimeModel } from "@opengeni/contracts";
2
- import type { Database } from "./index";
2
+ import type { Database } from "./database";
3
3
  import * as schema from "./schema";
4
4
  export { sessionRealtimeIsActiveInTransaction } from "./session-realtime-state";
5
5
  export declare const SESSION_REALTIME_LEASE_MS = 30000;
@@ -1,5 +1,5 @@
1
1
  import type { SessionEvent } from "@opengeni/contracts";
2
- import type { Database } from "./index";
2
+ import type { Database } from "./database";
3
3
  export declare const TOOL_RESULT_TYPE_BY_CALL_TYPE: Readonly<Record<string, string>>;
4
4
  export declare function historyCallId(item: Record<string, unknown>): string | null;
5
5
  export declare function historyItemType(item: Record<string, unknown>): string | null;
@@ -1,5 +1,5 @@
1
1
  import { type TurnInitiator, type TurnInitiatorContext } from "@opengeni/contracts";
2
- import type { Database } from "./index";
2
+ import type { Database } from "./database";
3
3
  import type { SessionCommandActor } from "./session-control";
4
4
  export declare const UNATTRIBUTED_LEGACY_INITIATOR: TurnInitiator;
5
5
  export type FrozenTurnInitiator = {
@@ -1,5 +1,5 @@
1
1
  import type { WorkspaceArtifact, WorkspaceArtifactDetailResponse, WorkspaceArtifactMutationResponse, WorkspaceArtifactVersion } from "@opengeni/contracts";
2
- import type { Database } from "./index";
2
+ import type { Database } from "./database";
3
3
  type ArtifactMutationToolName = "artifacts_create" | "artifacts_publish" | "artifacts_rollback";
4
4
  export declare class WorkspaceArtifactNotFoundError extends Error {
5
5
  readonly name = "WorkspaceArtifactNotFoundError";
@@ -1,6 +1,6 @@
1
1
  import { WorkspaceInstructionPolicySnapshot } from "@opengeni/contracts";
2
2
  import type { WorkspaceInstructionPolicyActivationResponse, WorkspaceInstructionPolicyDiffResponse, WorkspaceInstructionPolicyDraftProvenanceSource, WorkspaceInstructionPolicyHead, WorkspaceInstructionPolicyListQuery, WorkspaceInstructionPolicyListResponse, WorkspaceInstructionPolicyOnboardingProposal, WorkspaceInstructionPolicyOnboardingProposalListQuery, WorkspaceInstructionPolicyOnboardingProposalListResponse, WorkspaceInstructionPolicyProvenanceSource, WorkspaceInstructionPolicyRevision, WorkspaceInstructionPolicyTarget } from "@opengeni/contracts";
3
- import type { Database } from "./index";
3
+ import type { Database } from "./database";
4
4
  type DraftRequestInput = WorkspaceInstructionPolicyTarget & {
5
5
  operationId: string;
6
6
  accountId: string;
@@ -0,0 +1,133 @@
1
+ -- deployment-mode: rolling
2
+ -- Preserve control-priority Temporal signals across coalesced session wakes.
3
+
4
+ SET lock_timeout = '5s';
5
+ SET statement_timeout = '10min';
6
+
7
+ ALTER TABLE "session_workflow_wake_outbox"
8
+ ADD COLUMN "control_revision" bigint NOT NULL DEFAULT 0;
9
+
10
+ ALTER TABLE "session_workflow_wake_outbox"
11
+ ADD CONSTRAINT "session_workflow_wake_outbox_control_revision_check"
12
+ CHECK (
13
+ "control_revision" >= 0
14
+ AND "control_revision" <= "wake_revision"
15
+ AND "control_revision" <= 9007199254740991
16
+ ) NOT VALID;
17
+
18
+ -- Mixed-version writers do not know the new column. Stamp recognized control
19
+ -- reasons in the database so an old Steer followed by an old Send still leaves
20
+ -- the earlier control revision outstanding until delivery.
21
+ CREATE OR REPLACE FUNCTION opengeni_private.stamp_session_workflow_control_revision()
22
+ RETURNS trigger
23
+ LANGUAGE plpgsql
24
+ SET search_path = pg_catalog
25
+ AS $function$
26
+ BEGIN
27
+ IF NEW.reason IN (
28
+ 'prompt_steer',
29
+ 'queue_steer',
30
+ 'agent_steer',
31
+ 'session_cancelled',
32
+ 'session_pause_interruption',
33
+ 'workspace_pause_interruption',
34
+ 'attempt_interruption_settled',
35
+ 'attempt_interruption_rejected_stale'
36
+ ) AND NEW.wake_revision > NEW.delivered_revision THEN
37
+ NEW.control_revision := greatest(NEW.control_revision, NEW.wake_revision);
38
+ END IF;
39
+ RETURN NEW;
40
+ END
41
+ $function$;
42
+
43
+ DROP TRIGGER IF EXISTS session_workflow_wake_control_revision
44
+ ON "session_workflow_wake_outbox";
45
+ CREATE TRIGGER session_workflow_wake_control_revision
46
+ BEFORE INSERT OR UPDATE OF reason, wake_revision, control_revision
47
+ ON "session_workflow_wake_outbox"
48
+ FOR EACH ROW
49
+ EXECUTE FUNCTION opengeni_private.stamp_session_workflow_control_revision();
50
+
51
+ -- Preserve already-committed ownerless Steer/cancellation wakes during rolling
52
+ -- activation. Active-attempt controls remain independently discoverable from
53
+ -- the interruption ledger below.
54
+ UPDATE "session_workflow_wake_outbox"
55
+ SET "control_revision" = "wake_revision"
56
+ WHERE "delivered_revision" < "wake_revision"
57
+ AND "reason" IN (
58
+ 'prompt_steer',
59
+ 'queue_steer',
60
+ 'agent_steer',
61
+ 'session_cancelled',
62
+ 'session_pause_interruption',
63
+ 'workspace_pause_interruption'
64
+ );
65
+
66
+ ALTER TABLE "session_workflow_wake_outbox"
67
+ VALIDATE CONSTRAINT "session_workflow_wake_outbox_control_revision_check";
68
+
69
+ DROP FUNCTION opengeni_private.claim_session_workflow_wakes(integer);
70
+ DO $migration$
71
+ DECLARE target_schema text := current_schema();
72
+ BEGIN
73
+ EXECUTE format($create$
74
+ CREATE FUNCTION opengeni_private.claim_session_workflow_wakes(p_limit integer)
75
+ RETURNS TABLE (
76
+ account_id uuid,
77
+ workspace_id uuid,
78
+ session_id uuid,
79
+ temporal_workflow_id text,
80
+ wake_revision bigint,
81
+ interruption_requested boolean
82
+ )
83
+ LANGUAGE plpgsql
84
+ SECURITY DEFINER
85
+ SET search_path = pg_catalog
86
+ AS $function$
87
+ BEGIN
88
+ RETURN QUERY
89
+ WITH due AS (
90
+ SELECT o.session_id
91
+ FROM %1$I.session_workflow_wake_outbox o
92
+ WHERE o.wake_revision > o.delivered_revision
93
+ AND o.next_attempt_at <= now()
94
+ ORDER BY o.next_attempt_at, o.updated_at, o.session_id
95
+ FOR UPDATE SKIP LOCKED
96
+ LIMIT greatest(1, least(coalesce(p_limit, 100), 1000))
97
+ )
98
+ UPDATE %1$I.session_workflow_wake_outbox o
99
+ SET attempts = o.attempts + 1,
100
+ next_attempt_at = now() + make_interval(
101
+ secs => least(300, greatest(1, power(2, least(o.attempts, 8))::integer))
102
+ ),
103
+ updated_at = now()
104
+ FROM due
105
+ WHERE o.session_id = due.session_id
106
+ RETURNING o.account_id, o.workspace_id, o.session_id,
107
+ o.temporal_workflow_id, o.wake_revision,
108
+ o.control_revision > o.delivered_revision
109
+ OR EXISTS (
110
+ SELECT 1
111
+ FROM %1$I.session_attempt_interruptions interruption
112
+ WHERE interruption.workspace_id = o.workspace_id
113
+ AND interruption.session_id = o.session_id
114
+ AND interruption.state IN (
115
+ 'pending', 'delivered', 'acknowledged', 'settled', 'rejected_stale'
116
+ )
117
+ ) AS interruption_requested;
118
+ END $function$;
119
+ $create$, target_schema);
120
+ END $migration$;
121
+
122
+ REVOKE ALL ON FUNCTION opengeni_private.claim_session_workflow_wakes(integer) FROM PUBLIC;
123
+
124
+ DO $$
125
+ BEGIN
126
+ IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'opengeni_app') THEN
127
+ GRANT EXECUTE ON FUNCTION opengeni_private.claim_session_workflow_wakes(integer)
128
+ TO opengeni_app;
129
+ END IF;
130
+ END $$;
131
+
132
+ RESET statement_timeout;
133
+ RESET lock_timeout;
@@ -0,0 +1,53 @@
1
+ -- deployment-mode: rolling
2
+ -- Extend first-party social credentials with the same workspace/personal ownership boundary as MCP connections.
3
+
4
+ ALTER TABLE social_connections
5
+ ADD COLUMN subject_id text;
6
+
7
+ DROP INDEX social_connections_workspace_provider_handle_idx;
8
+ CREATE UNIQUE INDEX social_connections_workspace_provider_handle_idx
9
+ ON social_connections (workspace_id, provider, account_handle)
10
+ WHERE subject_id IS NULL;
11
+ CREATE UNIQUE INDEX social_connections_subject_provider_handle_idx
12
+ ON social_connections (workspace_id, subject_id, provider)
13
+ WHERE subject_id IS NOT NULL;
14
+ CREATE INDEX social_connections_subject_provider_status_idx
15
+ ON social_connections (workspace_id, subject_id, provider, status);
16
+
17
+ DROP POLICY workspace_isolation ON social_connections;
18
+ CREATE POLICY workspace_isolation ON social_connections
19
+ USING (
20
+ opengeni_private.workspace_rls_visible(account_id, workspace_id)
21
+ AND (
22
+ subject_id IS NULL
23
+ OR subject_id = nullif(current_setting('opengeni.subject_id', true), '')
24
+ )
25
+ )
26
+ WITH CHECK (
27
+ opengeni_private.workspace_rls_visible(account_id, workspace_id)
28
+ AND (
29
+ subject_id IS NULL
30
+ OR subject_id = nullif(current_setting('opengeni.subject_id', true), '')
31
+ )
32
+ );
33
+
34
+ DROP POLICY workspace_isolation ON social_posts;
35
+ CREATE POLICY workspace_isolation ON social_posts
36
+ USING (
37
+ opengeni_private.workspace_rls_visible(account_id, workspace_id)
38
+ AND EXISTS (
39
+ SELECT 1
40
+ FROM social_connections connection
41
+ WHERE connection.id = social_posts.connection_id
42
+ AND connection.workspace_id = social_posts.workspace_id
43
+ )
44
+ )
45
+ WITH CHECK (
46
+ opengeni_private.workspace_rls_visible(account_id, workspace_id)
47
+ AND EXISTS (
48
+ SELECT 1
49
+ FROM social_connections connection
50
+ WHERE connection.id = social_posts.connection_id
51
+ AND connection.workspace_id = social_posts.workspace_id
52
+ )
53
+ );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeni/db",
3
- "version": "0.27.7",
3
+ "version": "0.27.9",
4
4
  "description": "OpenGeni persistence: Drizzle schema, RLS-scoped query layer, the SQL migration runner, and role provisioning.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -51,8 +51,8 @@
51
51
  },
52
52
  "dependencies": {
53
53
  "@opengeni/codex": "^0.2.10",
54
- "@opengeni/config": "^0.10.11",
55
- "@opengeni/contracts": "^0.38.1",
54
+ "@opengeni/config": "^0.10.12",
55
+ "@opengeni/contracts": "^0.38.2",
56
56
  "@opengeni/network": "^0.2.0",
57
57
  "drizzle-orm": "^0.45.2",
58
58
  "postgres": "^3.4.7"