@opengeni/db 3.7.4 → 3.8.2-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 (77) hide show
  1. package/dist/automations.d.ts +4 -0
  2. package/dist/canonical-human-identities.js +3 -3
  3. package/dist/{chunk-O56DM5GZ.js → chunk-53A2PEHT.js} +328 -31
  4. package/dist/chunk-53A2PEHT.js.map +1 -0
  5. package/dist/{chunk-SZAWDXQC.js → chunk-5S4BQAHX.js} +3 -3
  6. package/dist/{chunk-S3TDDCS2.js → chunk-CITYUGMW.js} +3 -3
  7. package/dist/{chunk-4NAR7FBA.js → chunk-F5YOZEYQ.js} +49 -1
  8. package/dist/chunk-F5YOZEYQ.js.map +1 -0
  9. package/dist/{chunk-F6PBS6WE.js → chunk-HZV7O6JR.js} +2 -2
  10. package/dist/{chunk-5NNCGFQY.js → chunk-RLQVPOVR.js} +2 -2
  11. package/dist/{chunk-DZCYW2WT.js → chunk-UKOGHUGC.js} +2 -2
  12. package/dist/{chunk-US4IS6IV.js → chunk-X6TO5HII.js} +2 -2
  13. package/dist/{chunk-U4WPPEBH.js → chunk-Y53WEFYB.js} +2 -2
  14. package/dist/connection-token-resolver.d.ts +4 -0
  15. package/dist/editable-artifact-durable-export.js +2 -2
  16. package/dist/editable-artifacts.js +3 -3
  17. package/dist/index.d.ts +164 -14
  18. package/dist/index.js +7327 -5442
  19. package/dist/index.js.map +1 -1
  20. package/dist/insights.d.ts +9 -0
  21. package/dist/managed-auth-session-sets.js +3 -3
  22. package/dist/model-catalog.d.ts +153 -0
  23. package/dist/new-session-drafts.d.ts +12 -0
  24. package/dist/organization-membership-lifecycle.d.ts +8 -1
  25. package/dist/organization-model-providers.d.ts +101 -0
  26. package/dist/pack-components.d.ts +1 -0
  27. package/dist/pr-review.d.ts +9 -0
  28. package/dist/provision-roles.js +1 -1
  29. package/dist/runtime-posture.d.ts +7 -7
  30. package/dist/schema.d.ts +989 -2
  31. package/dist/schema.js +11 -1
  32. package/dist/session-background-commands.js +3 -3
  33. package/dist/session-control.d.ts +35 -0
  34. package/dist/session-queue-commands.d.ts +17 -0
  35. package/dist/session-tenancy.js +3 -3
  36. package/dist/video-generation.js +3 -3
  37. package/dist/xai-subscription.d.ts +8 -0
  38. package/drizzle/0387_bound_host_export_session_payloads.sql +165 -0
  39. package/drizzle/0388_sandbox_provider_deadline_interactions.sql +491 -0
  40. package/drizzle/0389_model_catalog_and_gateway_custom_models.sql +241 -0
  41. package/drizzle/0390_organization_model_provider_connections.sql +197 -0
  42. package/drizzle/0391_sandbox_provider_deadline_interaction_followup.sql +295 -0
  43. package/drizzle/0392_context_compaction_pending_observability.sql +198 -0
  44. package/drizzle/0393_workspace_memory_and_learning_defaults.sql +102 -0
  45. package/drizzle/0394_session_selected_skill_activation.sql +20 -0
  46. package/drizzle/0395_scheduled_task_unclaimed_occurrence_invalidation.sql +154 -0
  47. package/drizzle/0396_model_call_equivalent_credit_cost.sql +28 -0
  48. package/drizzle/0397_sandbox_deadline_rotation_preemption.sql +113 -0
  49. package/drizzle/0398_organization_workspace_management_entry.sql +206 -0
  50. package/drizzle/0399_additional_managed_organization_creation.sql +691 -0
  51. package/package.json +6 -6
  52. package/src/automations.ts +9 -1
  53. package/src/connection-token-resolver.ts +12 -0
  54. package/src/index.ts +1551 -272
  55. package/src/insights-model-bundle.ts +54 -5
  56. package/src/insights.ts +53 -7
  57. package/src/model-catalog.ts +682 -0
  58. package/src/new-session-drafts.ts +66 -21
  59. package/src/organization-membership-lifecycle.ts +47 -5
  60. package/src/organization-model-providers.ts +614 -0
  61. package/src/pack-components.ts +15 -2
  62. package/src/pr-review.ts +19 -0
  63. package/src/provision-roles.ts +2 -0
  64. package/src/runtime-posture.ts +48 -0
  65. package/src/schema.ts +348 -32
  66. package/src/session-control.ts +170 -0
  67. package/src/session-queue-commands.ts +157 -82
  68. package/src/xai-subscription.ts +66 -14
  69. package/dist/chunk-4NAR7FBA.js.map +0 -1
  70. package/dist/chunk-O56DM5GZ.js.map +0 -1
  71. /package/dist/{chunk-SZAWDXQC.js.map → chunk-5S4BQAHX.js.map} +0 -0
  72. /package/dist/{chunk-S3TDDCS2.js.map → chunk-CITYUGMW.js.map} +0 -0
  73. /package/dist/{chunk-F6PBS6WE.js.map → chunk-HZV7O6JR.js.map} +0 -0
  74. /package/dist/{chunk-5NNCGFQY.js.map → chunk-RLQVPOVR.js.map} +0 -0
  75. /package/dist/{chunk-DZCYW2WT.js.map → chunk-UKOGHUGC.js.map} +0 -0
  76. /package/dist/{chunk-US4IS6IV.js.map → chunk-X6TO5HII.js.map} +0 -0
  77. /package/dist/{chunk-U4WPPEBH.js.map → chunk-Y53WEFYB.js.map} +0 -0
@@ -1884,6 +1884,174 @@ async function findCommandReceipt(
1884
1884
  return rows[0] ?? null;
1885
1885
  }
1886
1886
 
1887
+ export type SessionPromptCommandAction = "prompt.send" | "prompt.steer";
1888
+
1889
+ async function findPromptCommandReceipts(
1890
+ db: Database,
1891
+ input: {
1892
+ workspaceId: string;
1893
+ actor: SessionCommandActor;
1894
+ operationKey: string;
1895
+ lock?: "none" | "update";
1896
+ },
1897
+ ): Promise<SessionCommandReceiptRow[]> {
1898
+ const actorSubjectId = input.actor.type === "agent_attempt" ? null : input.actor.subjectId;
1899
+ const actorAttemptId = input.actor.type === "agent_attempt" ? input.actor.attemptId : null;
1900
+ const query = db
1901
+ .select()
1902
+ .from(schema.sessionCommandReceipts)
1903
+ .where(
1904
+ and(
1905
+ eq(schema.sessionCommandReceipts.workspaceId, input.workspaceId),
1906
+ eq(schema.sessionCommandReceipts.actorType, input.actor.type),
1907
+ sql`${schema.sessionCommandReceipts.actorSubjectId} is not distinct from ${actorSubjectId}`,
1908
+ sql`${schema.sessionCommandReceipts.actorAttemptId} is not distinct from ${actorAttemptId}::uuid`,
1909
+ inArray(schema.sessionCommandReceipts.action, ["prompt.send", "prompt.steer"]),
1910
+ eq(schema.sessionCommandReceipts.operationKey, input.operationKey),
1911
+ ),
1912
+ );
1913
+ const rows = input.lock === "update" ? await query.for("update") : await query;
1914
+ return rows;
1915
+ }
1916
+
1917
+ function fingerprintedPromptCommandReceipt(
1918
+ receipts: readonly SessionCommandReceiptRow[],
1919
+ ): SessionCommandReceiptRow | null {
1920
+ const fingerprinted = receipts.filter(
1921
+ (receipt) => typeof receipt.result.boundaryRequestHash === "string",
1922
+ );
1923
+ if (fingerprinted.length > 1) {
1924
+ throw new SessionControlInvariantError(
1925
+ "Prompt operation key resolved to multiple fingerprinted receipts",
1926
+ );
1927
+ }
1928
+ return fingerprinted[0] ?? null;
1929
+ }
1930
+
1931
+ function assertPromptCommandReceiptIdentity(
1932
+ receipt: SessionCommandReceiptRow,
1933
+ input: {
1934
+ action: SessionPromptCommandAction;
1935
+ targetSessionId: string;
1936
+ boundaryRequestHash: string;
1937
+ },
1938
+ ): void {
1939
+ if (
1940
+ receipt.action !== input.action ||
1941
+ receipt.targetSessionId !== input.targetSessionId ||
1942
+ receipt.targetTurnId !== null ||
1943
+ (typeof receipt.result.boundaryRequestHash === "string" &&
1944
+ receipt.result.boundaryRequestHash !== input.boundaryRequestHash)
1945
+ ) {
1946
+ throw new SessionCommandIdempotencyError();
1947
+ }
1948
+ }
1949
+
1950
+ /**
1951
+ * Prompt operation keys are actor-scoped across target sessions and across the
1952
+ * Send/Steer action pair. The advisory lock closes the gap left by the legacy
1953
+ * action/target-specific unique index without changing old receipt identities.
1954
+ */
1955
+ export async function reserveSessionPromptCommandReceipt(
1956
+ db: Database,
1957
+ input: {
1958
+ accountId: string;
1959
+ workspaceId: string;
1960
+ actor: SessionCommandActor;
1961
+ action: SessionPromptCommandAction;
1962
+ targetSessionId: string;
1963
+ operationKey: string;
1964
+ canonicalRequestHash: string;
1965
+ boundaryRequestHash: string;
1966
+ },
1967
+ ): Promise<{ receipt: SessionCommandReceiptRow; replay: boolean }> {
1968
+ await lockSessionPromptCommandOperation(db, input);
1969
+ const existingReceipts = await findPromptCommandReceipts(db, {
1970
+ workspaceId: input.workspaceId,
1971
+ actor: input.actor,
1972
+ operationKey: input.operationKey,
1973
+ lock: "update",
1974
+ });
1975
+ const fingerprinted = fingerprintedPromptCommandReceipt(existingReceipts);
1976
+ if (fingerprinted) {
1977
+ assertPromptCommandReceiptIdentity(fingerprinted, input);
1978
+ return { receipt: fingerprinted, replay: true };
1979
+ }
1980
+ const legacyExact = existingReceipts.find(
1981
+ (receipt) =>
1982
+ receipt.action === input.action &&
1983
+ receipt.targetSessionId === input.targetSessionId &&
1984
+ receipt.targetTurnId === null,
1985
+ );
1986
+ if (legacyExact) {
1987
+ if (legacyExact.canonicalRequestHash !== input.canonicalRequestHash) {
1988
+ throw new SessionCommandIdempotencyError();
1989
+ }
1990
+ return { receipt: legacyExact, replay: true };
1991
+ }
1992
+ return await reserveSessionCommandReceipt(db, {
1993
+ accountId: input.accountId,
1994
+ workspaceId: input.workspaceId,
1995
+ actor: input.actor,
1996
+ action: input.action,
1997
+ targetSessionId: input.targetSessionId,
1998
+ targetTurnId: null,
1999
+ operationKey: input.operationKey,
2000
+ canonicalRequestHash: input.canonicalRequestHash,
2001
+ ...(existingReceipts.length === 0
2002
+ ? { initialResult: { boundaryRequestHash: input.boundaryRequestHash } }
2003
+ : {}),
2004
+ });
2005
+ }
2006
+
2007
+ /** Serialize one actor-scoped prompt operation before replay or reservation. */
2008
+ export async function lockSessionPromptCommandOperation(
2009
+ db: Database,
2010
+ input: {
2011
+ workspaceId: string;
2012
+ actor: SessionCommandActor;
2013
+ operationKey: string;
2014
+ },
2015
+ ): Promise<void> {
2016
+ const actorIdentity =
2017
+ input.actor.type === "agent_attempt"
2018
+ ? `attempt:${input.actor.attemptId}`
2019
+ : `${input.actor.type}:${input.actor.subjectId}`;
2020
+ await db.execute(
2021
+ sql`select pg_advisory_xact_lock(hashtextextended(${`session-prompt:${input.workspaceId}:${actorIdentity}:${input.operationKey}`}, 0))`,
2022
+ );
2023
+ }
2024
+
2025
+ /** Return only a fully committed exact prompt receipt with the new boundary fingerprint. */
2026
+ export async function getCompletedSessionPromptCommandReceipt(
2027
+ db: Database,
2028
+ input: {
2029
+ workspaceId: string;
2030
+ actor: SessionCommandActor;
2031
+ action: SessionPromptCommandAction;
2032
+ targetSessionId: string;
2033
+ operationKey: string;
2034
+ boundaryRequestHash: string;
2035
+ },
2036
+ ): Promise<SessionCommandReceiptRow | null> {
2037
+ const receipt = fingerprintedPromptCommandReceipt(
2038
+ await findPromptCommandReceipts(db, {
2039
+ workspaceId: input.workspaceId,
2040
+ actor: input.actor,
2041
+ operationKey: input.operationKey,
2042
+ }),
2043
+ );
2044
+ if (!receipt) return null;
2045
+ assertPromptCommandReceiptIdentity(receipt, input);
2046
+ if (
2047
+ typeof receipt.result.boundaryRequestHash !== "string" ||
2048
+ receipt.appliedQueueVersion === null
2049
+ ) {
2050
+ return null;
2051
+ }
2052
+ return receipt;
2053
+ }
2054
+
1887
2055
  export async function reserveSessionCommandReceipt(
1888
2056
  db: Database,
1889
2057
  input: {
@@ -1896,6 +2064,7 @@ export async function reserveSessionCommandReceipt(
1896
2064
  operationKey: string;
1897
2065
  canonicalRequestHash: string;
1898
2066
  identityScope?: "actor" | "goal_operation";
2067
+ initialResult?: Record<string, unknown>;
1899
2068
  },
1900
2069
  ): Promise<{ receipt: SessionCommandReceiptRow; replay: boolean }> {
1901
2070
  if (!input.operationKey.trim()) throw new Error("operationKey must not be empty");
@@ -1926,6 +2095,7 @@ export async function reserveSessionCommandReceipt(
1926
2095
  targetTurnId: input.targetTurnId,
1927
2096
  operationKey: input.operationKey,
1928
2097
  canonicalRequestHash: input.canonicalRequestHash,
2098
+ result: input.initialResult ?? {},
1929
2099
  })
1930
2100
  .onConflictDoNothing()
1931
2101
  .returning();
@@ -44,10 +44,13 @@ import {
44
44
  canonicalSessionCommandHash,
45
45
  evaluateSessionControl,
46
46
  lockSessionEventWriteRows,
47
+ lockSessionPromptCommandOperation,
47
48
  lockWorkspaceInferenceControl,
48
49
  lockWorkspaceInferenceControlForAdmission,
50
+ getCompletedSessionPromptCommandReceipt,
49
51
  registerInternalUpdateWakeInTransaction,
50
52
  reserveSessionCommandReceipt,
53
+ reserveSessionPromptCommandReceipt,
51
54
  registerSessionWorkflowWakeInTransaction,
52
55
  type SessionCommandActor,
53
56
  type SessionCommandReceiptRow,
@@ -210,6 +213,122 @@ function mapSubmittedPromptTurn(row: typeof schema.sessionTurns.$inferSelect): S
210
213
  };
211
214
  }
212
215
 
216
+ async function loadSubmittedHumanPromptReplay(
217
+ db: Database,
218
+ input: {
219
+ workspaceId: string;
220
+ sessionId: string;
221
+ subjectId: string;
222
+ delivery: "send" | "steer";
223
+ expectedDraftRevision?: number | null;
224
+ receipt: SessionCommandReceiptRow;
225
+ },
226
+ ): Promise<SubmitHumanPromptResult> {
227
+ const turnId = String(input.receipt.result.turnId ?? "");
228
+ const acceptedEventId = String(input.receipt.result.acceptedEventId ?? "");
229
+ const eventIds = Array.isArray(input.receipt.result.eventIds)
230
+ ? input.receipt.result.eventIds.filter((id): id is string => typeof id === "string")
231
+ : [];
232
+ const wakeRevision = Number(input.receipt.result.wakeRevision ?? 0);
233
+ if (!turnId || !acceptedEventId || wakeRevision < 1) {
234
+ throw new SessionControlInvariantError("Replayed prompt receipt is incomplete");
235
+ }
236
+ const replayEvents = await db
237
+ .select()
238
+ .from(schema.sessionEvents)
239
+ .where(
240
+ and(
241
+ eq(schema.sessionEvents.workspaceId, input.workspaceId),
242
+ eq(schema.sessionEvents.sessionId, input.sessionId),
243
+ inArray(schema.sessionEvents.id, eventIds),
244
+ ),
245
+ )
246
+ .orderBy(asc(schema.sessionEvents.sequence));
247
+ const [replayTurn] = await db
248
+ .select()
249
+ .from(schema.sessionTurns)
250
+ .where(
251
+ and(
252
+ eq(schema.sessionTurns.workspaceId, input.workspaceId),
253
+ eq(schema.sessionTurns.sessionId, input.sessionId),
254
+ eq(schema.sessionTurns.id, turnId),
255
+ ),
256
+ )
257
+ .limit(1);
258
+ const events = replayEvents.map(mapSubmittedPromptEvent);
259
+ const accepted = events.find((event) => event.id === acceptedEventId);
260
+ if (!accepted || !replayTurn || events.length !== eventIds.length) {
261
+ throw new SessionControlInvariantError("Replayed prompt rows are incomplete");
262
+ }
263
+ const replayDraft =
264
+ input.expectedDraftRevision === null || input.expectedDraftRevision === undefined
265
+ ? null
266
+ : await getComposerDraftInTransaction(db, {
267
+ workspaceId: input.workspaceId,
268
+ sessionId: input.sessionId,
269
+ subjectId: input.subjectId,
270
+ });
271
+ return {
272
+ receipt: input.receipt,
273
+ routing:
274
+ input.receipt.result.routing === "accepted_for_execution" ||
275
+ input.receipt.result.routing === "queued_for_execution" ||
276
+ input.receipt.result.routing === "accepted_for_steering"
277
+ ? input.receipt.result.routing
278
+ : input.delivery === "steer"
279
+ ? "accepted_for_steering"
280
+ : // Pre-routing receipts cannot reconstruct admission-time activity
281
+ // or Pause truth. Queue is the only conservative placement; a
282
+ // later turn.started event moves it into chat without duplication.
283
+ "queued_for_execution",
284
+ queueVersion: Number(input.receipt.appliedQueueVersion),
285
+ accepted,
286
+ events,
287
+ turn: mapSubmittedPromptTurn(replayTurn),
288
+ draft: replayDraft,
289
+ acceptedEventId,
290
+ eventIds,
291
+ turnId,
292
+ wakeRevision,
293
+ interruptionCount: Number(input.receipt.result.interruptionCount ?? 0),
294
+ workspaceControlEventId:
295
+ typeof input.receipt.result.workspaceControlEventId === "string"
296
+ ? input.receipt.result.workspaceControlEventId
297
+ : null,
298
+ replay: true,
299
+ };
300
+ }
301
+
302
+ export async function replaySubmittedHumanPromptFromBoundaryReceipt(
303
+ db: Database,
304
+ input: {
305
+ workspaceId: string;
306
+ sessionId: string;
307
+ subjectId: string;
308
+ actor: SessionCommandActor;
309
+ operationKey: string;
310
+ delivery: "send" | "steer";
311
+ boundaryRequestHash: string;
312
+ expectedDraftRevision?: number | null;
313
+ /** Wait for an overlapping same-key transaction before checking committed replay truth. */
314
+ serializeOperation?: boolean;
315
+ },
316
+ ): Promise<SubmitHumanPromptResult | null> {
317
+ if (input.serializeOperation) {
318
+ await lockSessionPromptCommandOperation(db, input);
319
+ }
320
+ const receipt = await getCompletedSessionPromptCommandReceipt(db, {
321
+ workspaceId: input.workspaceId,
322
+ actor: input.actor,
323
+ action: input.delivery === "steer" ? "prompt.steer" : "prompt.send",
324
+ targetSessionId: input.sessionId,
325
+ operationKey: input.operationKey,
326
+ boundaryRequestHash: input.boundaryRequestHash,
327
+ });
328
+ if (!receipt) return null;
329
+ return await loadSubmittedHumanPromptReplay(db, { ...input, receipt });
330
+ }
331
+
213
332
  export type AgentInternalUpdateCommandResult = {
214
333
  receipt: SessionCommandReceiptRow;
215
334
  updateId: string;
@@ -1608,6 +1727,8 @@ export async function submitHumanPromptInTransaction(
1608
1727
  subjectLabel?: string;
1609
1728
  actor: SessionCommandActor;
1610
1729
  operationKey: string;
1730
+ /** Stable parsed boundary-request identity used before mutable enrichment. */
1731
+ boundaryRequestHash?: string;
1611
1732
  delivery: "send" | "steer";
1612
1733
  controlEtag?: string | null;
1613
1734
  expectedDraftRevision?: number | null;
@@ -1642,6 +1763,9 @@ export async function submitHumanPromptInTransaction(
1642
1763
  id: string;
1643
1764
  headersEncrypted: Record<string, string>;
1644
1765
  }>;
1766
+ /** Trusted database-only admission seam. It runs only after a completed
1767
+ * operation replay has been ruled out; throwing rolls the prompt back. */
1768
+ beforeFreshPromptCommit?: (tx: Database) => Promise<void>;
1645
1769
  /** Request-scoped callers bound the control prefix wait; lifecycle callers omit it. */
1646
1770
  controlLockTimeoutMs?: number;
1647
1771
  },
@@ -1708,91 +1832,41 @@ export async function submitHumanPromptInTransaction(
1708
1832
  }
1709
1833
  : {}),
1710
1834
  });
1711
- const reserved = await reserveSessionCommandReceipt(db, {
1712
- accountId: input.accountId,
1713
- workspaceId: input.workspaceId,
1714
- actor: input.actor,
1715
- action: input.delivery === "steer" ? "prompt.steer" : "prompt.send",
1716
- targetSessionId: input.sessionId,
1717
- targetTurnId: null,
1718
- operationKey: input.operationKey,
1719
- canonicalRequestHash: requestHash,
1720
- });
1835
+ const action = input.delivery === "steer" ? "prompt.steer" : "prompt.send";
1836
+ const reserved = input.boundaryRequestHash
1837
+ ? await reserveSessionPromptCommandReceipt(db, {
1838
+ accountId: input.accountId,
1839
+ workspaceId: input.workspaceId,
1840
+ actor: input.actor,
1841
+ action,
1842
+ targetSessionId: input.sessionId,
1843
+ operationKey: input.operationKey,
1844
+ canonicalRequestHash: requestHash,
1845
+ boundaryRequestHash: input.boundaryRequestHash,
1846
+ })
1847
+ : await reserveSessionCommandReceipt(db, {
1848
+ accountId: input.accountId,
1849
+ workspaceId: input.workspaceId,
1850
+ actor: input.actor,
1851
+ action,
1852
+ targetSessionId: input.sessionId,
1853
+ targetTurnId: null,
1854
+ operationKey: input.operationKey,
1855
+ canonicalRequestHash: requestHash,
1856
+ });
1721
1857
  if (reserved.replay && reserved.receipt.appliedQueueVersion !== null) {
1722
- const turnId = String(reserved.receipt.result.turnId ?? "");
1723
- const acceptedEventId = String(reserved.receipt.result.acceptedEventId ?? "");
1724
- const eventIds = Array.isArray(reserved.receipt.result.eventIds)
1725
- ? reserved.receipt.result.eventIds.filter((id): id is string => typeof id === "string")
1726
- : [];
1727
- const wakeRevision = Number(reserved.receipt.result.wakeRevision ?? 0);
1728
- if (!turnId || !acceptedEventId || wakeRevision < 1) {
1729
- throw new SessionControlInvariantError("Replayed prompt receipt is incomplete");
1730
- }
1731
- const replayEvents = await db
1732
- .select()
1733
- .from(schema.sessionEvents)
1734
- .where(
1735
- and(
1736
- eq(schema.sessionEvents.workspaceId, input.workspaceId),
1737
- eq(schema.sessionEvents.sessionId, input.sessionId),
1738
- inArray(schema.sessionEvents.id, eventIds),
1739
- ),
1740
- )
1741
- .orderBy(asc(schema.sessionEvents.sequence));
1742
- const [replayTurn] = await db
1743
- .select()
1744
- .from(schema.sessionTurns)
1745
- .where(
1746
- and(
1747
- eq(schema.sessionTurns.workspaceId, input.workspaceId),
1748
- eq(schema.sessionTurns.sessionId, input.sessionId),
1749
- eq(schema.sessionTurns.id, turnId),
1750
- ),
1751
- )
1752
- .limit(1);
1753
- const events = replayEvents.map(mapSubmittedPromptEvent);
1754
- const accepted = events.find((event) => event.id === acceptedEventId);
1755
- if (!accepted || !replayTurn || events.length !== eventIds.length) {
1756
- throw new SessionControlInvariantError("Replayed prompt rows are incomplete");
1757
- }
1758
- const replayDraft =
1759
- input.expectedDraftRevision === null || input.expectedDraftRevision === undefined
1760
- ? null
1761
- : await getComposerDraftInTransaction(db, {
1762
- workspaceId: input.workspaceId,
1763
- sessionId: input.sessionId,
1764
- subjectId: input.subjectId,
1765
- });
1766
- return {
1858
+ return await loadSubmittedHumanPromptReplay(db, {
1859
+ workspaceId: input.workspaceId,
1860
+ sessionId: input.sessionId,
1861
+ subjectId: input.subjectId,
1862
+ delivery: input.delivery,
1863
+ ...(input.expectedDraftRevision !== undefined
1864
+ ? { expectedDraftRevision: input.expectedDraftRevision }
1865
+ : {}),
1767
1866
  receipt: reserved.receipt,
1768
- routing:
1769
- reserved.receipt.result.routing === "accepted_for_execution" ||
1770
- reserved.receipt.result.routing === "queued_for_execution" ||
1771
- reserved.receipt.result.routing === "accepted_for_steering"
1772
- ? reserved.receipt.result.routing
1773
- : input.delivery === "steer"
1774
- ? "accepted_for_steering"
1775
- : // Pre-routing receipts cannot reconstruct admission-time activity
1776
- // or Pause truth. Queue is the only conservative placement; a
1777
- // later turn.started event moves it into chat without duplication.
1778
- "queued_for_execution",
1779
- queueVersion: Number(reserved.receipt.appliedQueueVersion),
1780
- accepted,
1781
- events,
1782
- turn: mapSubmittedPromptTurn(replayTurn),
1783
- draft: replayDraft,
1784
- acceptedEventId,
1785
- eventIds,
1786
- turnId,
1787
- wakeRevision,
1788
- interruptionCount: Number(reserved.receipt.result.interruptionCount ?? 0),
1789
- workspaceControlEventId:
1790
- typeof reserved.receipt.result.workspaceControlEventId === "string"
1791
- ? reserved.receipt.result.workspaceControlEventId
1792
- : null,
1793
- replay: true,
1794
- };
1867
+ });
1795
1868
  }
1869
+ await input.beforeFreshPromptCommit?.(db);
1796
1870
 
1797
1871
  const before = await evaluateSessionControl(db, input.workspaceId, input.sessionId, {
1798
1872
  workspaceControl,
@@ -2434,6 +2508,7 @@ export async function submitHumanPromptInTransaction(
2434
2508
  turnVersion: turn.version,
2435
2509
  ...(nextDraft ? { draftRevision: nextDraft.revision } : {}),
2436
2510
  result: {
2511
+ ...(input.boundaryRequestHash ? { boundaryRequestHash: input.boundaryRequestHash } : {}),
2437
2512
  turnId,
2438
2513
  acceptedEventId,
2439
2514
  eventIds,
@@ -472,20 +472,72 @@ export async function workspaceXaiSubscriptionActive(
472
472
  workspaceId,
473
473
  subjectId,
474
474
  });
475
- const [accounts, rotation] = await Promise.all([
476
- listXaiSubscriptionAccountsMetadata(db, { workspaceId, subjectId }),
477
- getXaiRotationSettings(db, { workspaceId, subjectId, authoritySnapshot }),
478
- ]);
479
- const activeCredentialId = rotation?.activeCredentialId ?? null;
480
- const now = new Date();
481
- const eligible = (account: XaiSubscriptionAccountMetadata) =>
482
- account.status === "active" &&
483
- account.allocatorEnabled &&
484
- (!account.exhaustedUntil || account.exhaustedUntil <= now);
485
- if (rotation?.rotationEnabled !== false) {
486
- return accounts.some(eligible);
487
- }
488
- return accounts.some((account) => account.id === activeCredentialId && eligible(account));
475
+ return await workspaceXaiSubscriptionActiveForAuthority(db, settings, {
476
+ workspaceId,
477
+ subjectId,
478
+ authoritySnapshot,
479
+ });
480
+ }
481
+
482
+ /** Metadata-only readiness for the exact provider-account authority frozen on a turn. */
483
+ export async function workspaceXaiSubscriptionActiveForAuthority(
484
+ db: Database,
485
+ settings: { readonly supergrokSubscriptionEnabled: boolean },
486
+ input: {
487
+ workspaceId: string;
488
+ subjectId: string;
489
+ authoritySnapshot: XaiAuthoritySnapshot;
490
+ },
491
+ ): Promise<boolean> {
492
+ if (!settings.supergrokSubscriptionEnabled) return false;
493
+ const snapshot = XaiProviderAccountAuthoritySnapshotV1.parse(input.authoritySnapshot);
494
+ return await withWorkspaceSubjectRls(db, input.workspaceId, input.subjectId, async (scopedDb) => {
495
+ const ownerMembershipId = await resolveXaiPoolOwnerMembershipId(scopedDb, {
496
+ workspaceId: input.workspaceId,
497
+ subjectId: input.subjectId,
498
+ authoritySnapshot: snapshot,
499
+ });
500
+ const ownerPredicate =
501
+ ownerMembershipId === null
502
+ ? isNull(schema.xaiSubscriptionCredentials.ownerOrganizationMembershipId)
503
+ : eq(schema.xaiSubscriptionCredentials.ownerOrganizationMembershipId, ownerMembershipId);
504
+ const [accounts, rotation] = await Promise.all([
505
+ scopedDb
506
+ .select(xaiCredentialMetadataColumns)
507
+ .from(schema.xaiSubscriptionCredentials)
508
+ .where(
509
+ and(
510
+ eq(schema.xaiSubscriptionCredentials.workspaceId, input.workspaceId),
511
+ eq(schema.xaiSubscriptionCredentials.authorityScope, snapshot.scope),
512
+ ownerPredicate,
513
+ ),
514
+ ),
515
+ scopedDb
516
+ .select()
517
+ .from(schema.xaiRotationSettings)
518
+ .where(
519
+ and(
520
+ eq(schema.xaiRotationSettings.workspaceId, input.workspaceId),
521
+ eq(schema.xaiRotationSettings.authorityScope, snapshot.scope),
522
+ ownerMembershipId === null
523
+ ? isNull(schema.xaiRotationSettings.ownerOrganizationMembershipId)
524
+ : eq(schema.xaiRotationSettings.ownerOrganizationMembershipId, ownerMembershipId),
525
+ ),
526
+ )
527
+ .limit(1)
528
+ .then((rows) => rows[0] ?? null),
529
+ ]);
530
+ const activeCredentialId = rotation?.activeCredentialId ?? null;
531
+ const now = new Date();
532
+ const eligible = (account: XaiCredentialMetadataRow) =>
533
+ account.status === "active" &&
534
+ account.allocatorEnabled &&
535
+ (!account.exhaustedUntil || account.exhaustedUntil <= now);
536
+ if (rotation?.rotationEnabled !== false) {
537
+ return accounts.some(eligible);
538
+ }
539
+ return accounts.some((account) => account.id === activeCredentialId && eligible(account));
540
+ });
489
541
  }
490
542
 
491
543
  export async function getXaiSubscriptionAccountMetadata(