@opengeni/db 1.0.2 → 1.1.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 (69) hide show
  1. package/dist/artifact-catalog.d.ts +12 -0
  2. package/dist/canonical-human-identities.js +3 -3
  3. package/dist/capability-reconciliation.js +2 -2
  4. package/dist/{chunk-KEDWSSNP.js → chunk-7Z7ALFRE.js} +2 -2
  5. package/dist/{chunk-OQZOGCLG.js → chunk-BLUQG54M.js} +2 -2
  6. package/dist/{chunk-Y77PVZZD.js → chunk-BZV5ZDRY.js} +2 -2
  7. package/dist/{chunk-MACELCXG.js → chunk-CIGHXFPD.js} +3 -3
  8. package/dist/{chunk-7S53WLPI.js → chunk-EKXCF3FH.js} +4 -4
  9. package/dist/{chunk-F3YMVRF4.js → chunk-GLA5YCQS.js} +4 -4
  10. package/dist/{chunk-KH3TYDGY.js → chunk-J4WFOVBV.js} +2 -2
  11. package/dist/{chunk-NLSG7GGA.js → chunk-KJVOBLFC.js} +3 -3
  12. package/dist/{chunk-7POTLB24.js → chunk-M2YGXCCQ.js} +2 -2
  13. package/dist/{chunk-PQGTWFRF.js → chunk-M3SWH4MU.js} +2 -2
  14. package/dist/{chunk-OMHBVHX7.js → chunk-ODKYBA3C.js} +5 -5
  15. package/dist/{chunk-56MYWKQV.js → chunk-SKYRM7R7.js} +2 -2
  16. package/dist/{chunk-N5QCKHYL.js → chunk-T5NHDEZW.js} +62 -19
  17. package/dist/chunk-T5NHDEZW.js.map +1 -0
  18. package/dist/{chunk-LDTQGYD2.js → chunk-VOB6TXSJ.js} +16 -1
  19. package/dist/chunk-VOB6TXSJ.js.map +1 -0
  20. package/dist/{chunk-UEQQ2WWU.js → chunk-Z5HJXH3X.js} +3 -26
  21. package/dist/chunk-Z5HJXH3X.js.map +1 -0
  22. package/dist/connect-attempts.js +3 -3
  23. package/dist/editable-artifact-durable-export.js +2 -2
  24. package/dist/editable-artifacts.js +3 -3
  25. package/dist/index.d.ts +14 -5
  26. package/dist/index.js +85 -30
  27. package/dist/index.js.map +1 -1
  28. package/dist/managed-auth-session-sets.js +3 -3
  29. package/dist/mcp-operations.js +2 -2
  30. package/dist/organization-integration-policy.js +3 -3
  31. package/dist/provision-roles.js +1 -1
  32. package/dist/retained-provider-commands.js +6 -6
  33. package/dist/runtime-posture.d.ts +3 -2
  34. package/dist/schema.d.ts +93 -0
  35. package/dist/schema.js +3 -1
  36. package/dist/session-background-commands.js +4 -4
  37. package/dist/session-command-output.js +5 -5
  38. package/dist/session-event-slices.js +3 -3
  39. package/dist/session-mcp-credential-rotation.js +5 -5
  40. package/dist/session-tenancy.d.ts +6 -1
  41. package/dist/session-tenancy.js +3 -5
  42. package/dist/video-generation.js +3 -3
  43. package/dist/workspace-tool-defaults.js +4 -4
  44. package/drizzle/0610_artifact_catalog_pins.sql +165 -0
  45. package/drizzle/0611_universal_session_tenancy_activation.sql +166 -0
  46. package/drizzle/0612_scheduled_model_unavailable_refusal.sql +21 -0
  47. package/package.json +7 -7
  48. package/src/artifact-catalog.ts +31 -5
  49. package/src/index.ts +94 -19
  50. package/src/provision-roles.ts +16 -0
  51. package/src/runtime-posture-cli.ts +0 -2
  52. package/src/runtime-posture.ts +64 -27
  53. package/src/schema.ts +17 -0
  54. package/src/session-tenancy.ts +9 -31
  55. package/dist/chunk-LDTQGYD2.js.map +0 -1
  56. package/dist/chunk-N5QCKHYL.js.map +0 -1
  57. package/dist/chunk-UEQQ2WWU.js.map +0 -1
  58. /package/dist/{chunk-KEDWSSNP.js.map → chunk-7Z7ALFRE.js.map} +0 -0
  59. /package/dist/{chunk-OQZOGCLG.js.map → chunk-BLUQG54M.js.map} +0 -0
  60. /package/dist/{chunk-Y77PVZZD.js.map → chunk-BZV5ZDRY.js.map} +0 -0
  61. /package/dist/{chunk-MACELCXG.js.map → chunk-CIGHXFPD.js.map} +0 -0
  62. /package/dist/{chunk-7S53WLPI.js.map → chunk-EKXCF3FH.js.map} +0 -0
  63. /package/dist/{chunk-F3YMVRF4.js.map → chunk-GLA5YCQS.js.map} +0 -0
  64. /package/dist/{chunk-KH3TYDGY.js.map → chunk-J4WFOVBV.js.map} +0 -0
  65. /package/dist/{chunk-NLSG7GGA.js.map → chunk-KJVOBLFC.js.map} +0 -0
  66. /package/dist/{chunk-7POTLB24.js.map → chunk-M2YGXCCQ.js.map} +0 -0
  67. /package/dist/{chunk-PQGTWFRF.js.map → chunk-M3SWH4MU.js.map} +0 -0
  68. /package/dist/{chunk-OMHBVHX7.js.map → chunk-ODKYBA3C.js.map} +0 -0
  69. /package/dist/{chunk-56MYWKQV.js.map → chunk-SKYRM7R7.js.map} +0 -0
@@ -2,10 +2,9 @@ import {
2
2
  nestedPostgresSqlState,
3
3
  rawRows,
4
4
  rlsContextForWorkspace,
5
- withWorkspaceRls,
6
5
  withWorkspaceSubjectRls,
7
6
  withWorkspaceSubjectSessionActivityRls
8
- } from "./chunk-56MYWKQV.js";
7
+ } from "./chunk-SKYRM7R7.js";
9
8
 
10
9
  // src/session-tenancy.ts
11
10
  import { createHash } from "crypto";
@@ -28,7 +27,7 @@ var SessionTenancyConflictError = class extends Error {
28
27
  var SessionTenancyNotActivatedError = class extends Error {
29
28
  name = "SessionTenancyNotActivatedError";
30
29
  constructor(options) {
31
- super("Session tenancy product surface is not activated for this organization", options);
30
+ super("Only-me chats are not enabled for this organization", options);
32
31
  }
33
32
  };
34
33
  var SessionTenancyAccessError = class extends Error {
@@ -65,19 +64,6 @@ function nestedSessionTenancyBlocker(error) {
65
64
  }
66
65
  return null;
67
66
  }
68
- async function sessionTenancyProductActivated(db, workspaceId) {
69
- const { accountId } = await rlsContextForWorkspace(db, workspaceId);
70
- return await withWorkspaceRls(db, workspaceId, async (scopedDb) => {
71
- const rows = await rawRows(
72
- scopedDb,
73
- sql`select session_tenancy_product_activated(
74
- ${accountId}::uuid,
75
- ${SESSION_TENANCY_ACTIVATION_VERSION}
76
- ) as activated`
77
- );
78
- return rows[0]?.activated === true;
79
- });
80
- }
81
67
  async function getPrivateSessionCreatePolicy(db, input) {
82
68
  const { accountId } = await rlsContextForWorkspace(db, input.workspaceId);
83
69
  return await withWorkspaceSubjectRls(
@@ -159,11 +145,6 @@ async function openPrivateChildSessionCreateCapability(db, input) {
159
145
  async function closePrivateSessionCreateCapability(db, capabilityId) {
160
146
  await db.execute(sql`select close_private_session_create_capability(${capabilityId}::uuid)`);
161
147
  }
162
- async function assertSessionTenancyProductActivated(db, workspaceId) {
163
- if (!await sessionTenancyProductActivated(db, workspaceId)) {
164
- throw new SessionTenancyNotActivatedError();
165
- }
166
- }
167
148
  function mapSessionTenancyPersistenceError(error, options) {
168
149
  const state = nestedPostgresSqlState(error);
169
150
  if (state === "55P03") {
@@ -251,7 +232,6 @@ async function transitionSessionVisibility(db, input) {
251
232
  if (!input.operationKey.trim()) throw new Error("operationKey must not be empty");
252
233
  const requestHash = canonicalSessionVisibilityTransitionHash(input);
253
234
  const { accountId } = await rlsContextForWorkspace(db, input.workspaceId);
254
- await assertSessionTenancyProductActivated(db, input.workspaceId);
255
235
  try {
256
236
  return await withWorkspaceSubjectSessionActivityRls(
257
237
  db,
@@ -313,7 +293,6 @@ async function forkSessionContent(db, input) {
313
293
  throw new Error("Resolved session fork runtime configuration does not match its request");
314
294
  }
315
295
  const { accountId } = await rlsContextForWorkspace(db, input.sourceWorkspaceId);
316
- await assertSessionTenancyProductActivated(db, input.sourceWorkspaceId);
317
296
  const requestHash = canonicalSessionForkHash(input);
318
297
  try {
319
298
  return await withWorkspaceSubjectRls(
@@ -408,7 +387,6 @@ async function replayAppliedSessionFork(db, input) {
408
387
  throw new Error("The first session fork contract is same-workspace only");
409
388
  }
410
389
  const { accountId } = await rlsContextForWorkspace(db, input.sourceWorkspaceId);
411
- await assertSessionTenancyProductActivated(db, input.sourceWorkspaceId);
412
390
  const requestHash = canonicalSessionForkHash(input);
413
391
  try {
414
392
  return await withWorkspaceSubjectRls(
@@ -491,7 +469,6 @@ export {
491
469
  SessionTenancyAccessError,
492
470
  SessionTenancyInvalidRequestError,
493
471
  nestedSessionTenancyBlocker,
494
- sessionTenancyProductActivated,
495
472
  getPrivateSessionCreatePolicy,
496
473
  openPrivateSessionCreateCapability,
497
474
  openPrivateChildSessionCreateCapability,
@@ -502,4 +479,4 @@ export {
502
479
  forkSessionContent,
503
480
  replayAppliedSessionFork
504
481
  };
505
- //# sourceMappingURL=chunk-UEQQ2WWU.js.map
482
+ //# sourceMappingURL=chunk-Z5HJXH3X.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/session-tenancy.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { sql } from \"drizzle-orm\";\nimport {\n SessionTenancyBlocker as SessionTenancyBlockerSchema,\n type SessionTenancyBlocker,\n} from \"@opengeni/contracts\";\nimport {\n rawRows,\n type Database,\n rlsContextForWorkspace,\n withWorkspaceSubjectRls,\n withWorkspaceSubjectSessionActivityRls,\n} from \"./database\";\nimport { nestedPostgresSqlState } from \"./persistence-errors\";\n\n// Frozen SQL protocol argument: every organization is activated at version 1\n// since migration 0611, but the lifecycle routines still require it explicitly.\nconst SESSION_TENANCY_ACTIVATION_VERSION = 1;\n\nexport class SessionTenancyConflictError extends Error {\n readonly name = \"SessionTenancyConflictError\";\n constructor(\n readonly reason: \"not_quiescent\" | \"authority_epoch\" | \"operation_reuse\",\n readonly blocker: SessionTenancyBlocker | null = null,\n options?: ErrorOptions,\n ) {\n super(\n reason === \"not_quiescent\"\n ? \"Session must be fully quiescent before its tenancy can change\"\n : reason === \"authority_epoch\"\n ? \"Session authority changed before the operation committed\"\n : \"Session tenancy operation key was reused with different input\",\n options,\n );\n }\n}\n\n/**\n * The organization's owner/admin Only-me setting does not permit a new private\n * session (or private transition) in this shared workspace. Activation itself is\n * universal since migration 0611; the name and the SESSION_TENANCY_NOT_ACTIVATED\n * wire code are kept for client compatibility.\n */\nexport class SessionTenancyNotActivatedError extends Error {\n readonly name = \"SessionTenancyNotActivatedError\";\n constructor(options?: ErrorOptions) {\n super(\"Only-me chats are not enabled for this organization\", options);\n }\n}\n\nexport class SessionTenancyAccessError extends Error {\n readonly name = \"SessionTenancyAccessError\";\n constructor(options?: ErrorOptions) {\n super(\"Session tenancy target is unavailable\", options);\n }\n}\n\nexport class SessionTenancyInvalidRequestError extends Error {\n readonly name = \"SessionTenancyInvalidRequestError\";\n constructor(options?: ErrorOptions) {\n super(\"Session tenancy request is invalid\", options);\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value && typeof value === \"object\");\n}\n\n/** Extract only the fixed quiescence DETAIL vocabulary, never arbitrary driver detail. */\nexport function nestedSessionTenancyBlocker(error: unknown): SessionTenancyBlocker | null {\n const queue: unknown[] = [error];\n const seen = new Set<unknown>();\n while (queue.length > 0 && seen.size < 64) {\n const current = queue.shift();\n if (!isRecord(current) || seen.has(current)) continue;\n seen.add(current);\n for (const key of [\"detail\", \"detailMessage\"] as const) {\n const parsed = SessionTenancyBlockerSchema.safeParse(current[key]);\n if (parsed.success) return parsed.data;\n }\n for (const key of [\"cause\", \"original\", \"driverError\", \"error\", \"errors\"] as const) {\n const nested = current[key];\n if (Array.isArray(nested)) queue.push(...nested);\n else if (nested !== undefined) queue.push(nested);\n }\n }\n return null;\n}\n\nexport type SessionTenancyVisibility = \"user_private\" | \"workspace_shared\";\n\nexport type PrivateSessionCreatePolicy = {\n personalWorkspace: boolean;\n platformAvailable: boolean;\n organizationEnabled: boolean;\n};\n\nexport type TransitionSessionVisibilityInput = {\n workspaceId: string;\n sessionId: string;\n actorSubjectId: string;\n targetVisibility: SessionTenancyVisibility;\n expectedAuthorityEpoch: number;\n operationKey: string;\n beforeCommit?: (tx: Database) => Promise<void>;\n};\n\nexport type TransitionSessionVisibilityResult = {\n operationId: string;\n eventId: string | null;\n eventSequence: number | null;\n visibility: SessionTenancyVisibility;\n authorityEpoch: number;\n ownerOrganizationMembershipId: string | null;\n changed: boolean;\n replay: boolean;\n interruptedAttemptCount: number;\n cancelledTurnCount: number;\n cancelledUpdateCount: number;\n pausedGoalCount: number;\n revokedGrantCount: number;\n};\n\nexport type ForkSessionContentInput = {\n sourceEventId?: string;\n sourceWorkspaceId: string;\n sourceSessionId: string;\n actorSubjectId: string;\n destinationWorkspaceId: string;\n destinationVisibility: SessionTenancyVisibility;\n workspaceSharedAcknowledged: boolean;\n operationKey: string;\n runtimeRequest?: ForkSessionRuntimeRequest;\n runtimeConfiguration?: ForkSessionRuntimeConfiguration;\n beforeCommit?: (tx: Database) => Promise<void>;\n};\n\nexport type ForkSessionRuntimeRequest = {\n variableSetIds: string[];\n rigId: string | null;\n};\n\nexport type ForkSessionRuntimeConfiguration = ForkSessionRuntimeRequest & {\n rigVersionId: string | null;\n};\n\nexport type ForkSessionContentResult = {\n operationId: string;\n eventId: string;\n eventSequence: number;\n sessionId: string;\n workspaceId: string;\n visibility: SessionTenancyVisibility;\n authorityEpoch: number;\n copiedHistoryItemCount: number;\n replay: boolean;\n runtimeEventId: string | null;\n runtimeEventSequence: number | null;\n};\n\nexport async function getPrivateSessionCreatePolicy(\n db: Database,\n input: { workspaceId: string; actorSubjectId: string },\n): Promise<PrivateSessionCreatePolicy> {\n const { accountId } = await rlsContextForWorkspace(db, input.workspaceId);\n return await withWorkspaceSubjectRls(\n db,\n input.workspaceId,\n input.actorSubjectId,\n async (scopedDb) => {\n const rows = await rawRows<{\n personalWorkspace: boolean;\n platformAvailable: boolean;\n organizationEnabled: boolean;\n }>(\n scopedDb,\n sql`select\n personal_workspace as \"personalWorkspace\",\n platform_available as \"platformAvailable\",\n organization_enabled as \"organizationEnabled\"\n from get_private_session_create_policy(\n ${accountId}::uuid,\n ${input.workspaceId}::uuid,\n ${input.actorSubjectId}\n )`,\n );\n const policy = rows[0];\n if (!policy) throw new SessionTenancyAccessError();\n return policy;\n },\n );\n}\n\n/** Open the exact transaction-local trigger capability used by atomic private create. */\nexport async function openPrivateSessionCreateCapability(\n db: Database,\n input: { accountId: string; workspaceId: string; sessionId: string; actorSubjectId: string },\n): Promise<{ capabilityId: string; ownerMembershipId: string }> {\n let rows: Array<{ capabilityId: string; ownerMembershipId: string }>;\n try {\n rows = await rawRows<{ capabilityId: string; ownerMembershipId: string }>(\n db,\n sql`select\n capability_id as \"capabilityId\",\n owner_membership_id as \"ownerMembershipId\"\n from open_private_session_create_capability(\n ${input.accountId}::uuid,\n ${input.workspaceId}::uuid,\n ${input.sessionId}::uuid,\n ${input.actorSubjectId}\n )`,\n );\n } catch (error) {\n // The definer raises 55000 only when the organization owner/admin setting\n // does not permit a new private session in this shared workspace; every\n // authority failure remains 42501 and propagates unchanged.\n if (nestedPostgresSqlState(error) === \"55000\") {\n throw new SessionTenancyNotActivatedError({ cause: error });\n }\n throw error;\n }\n const capabilityId = rows[0]?.capabilityId;\n const ownerMembershipId = rows[0]?.ownerMembershipId;\n if (!capabilityId || !ownerMembershipId) {\n throw new Error(\"Private session create capability was not returned\");\n }\n return { capabilityId, ownerMembershipId };\n}\n\n/** Open the exact transaction-local capability for one private child insert. */\nexport async function openPrivateChildSessionCreateCapability(\n db: Database,\n input: {\n accountId: string;\n workspaceId: string;\n sessionId: string;\n parentSessionId: string;\n actorTurnId: string;\n actorAttemptId: string;\n actorExecutionGeneration: number;\n },\n): Promise<{ capabilityId: string; ownerMembershipId: string; ownerSubjectId: string }> {\n const rows = await rawRows<{\n capabilityId: string;\n ownerMembershipId: string;\n ownerSubjectId: string;\n }>(\n db,\n sql`select\n capability_id as \"capabilityId\",\n owner_membership_id as \"ownerMembershipId\",\n owner_subject_id as \"ownerSubjectId\"\n from open_private_child_session_create_capability(\n ${input.accountId}::uuid,\n ${input.workspaceId}::uuid,\n ${input.sessionId}::uuid,\n ${input.parentSessionId}::uuid,\n ${input.actorTurnId}::uuid,\n ${input.actorAttemptId}::uuid,\n ${input.actorExecutionGeneration}::integer\n )`,\n );\n const capabilityId = rows[0]?.capabilityId;\n const ownerMembershipId = rows[0]?.ownerMembershipId;\n const ownerSubjectId = rows[0]?.ownerSubjectId;\n if (!capabilityId || !ownerMembershipId || !ownerSubjectId) {\n throw new Error(\"Private child session create capability was not returned\");\n }\n return { capabilityId, ownerMembershipId, ownerSubjectId };\n}\n\nexport async function closePrivateSessionCreateCapability(\n db: Database,\n capabilityId: string,\n): Promise<void> {\n await db.execute(sql`select close_private_session_create_capability(${capabilityId}::uuid)`);\n}\n\nfunction mapSessionTenancyPersistenceError(\n error: unknown,\n options: { authorityEpochConflict: boolean },\n): never {\n const state = nestedPostgresSqlState(error);\n if (state === \"55P03\") {\n throw new SessionTenancyConflictError(\"not_quiescent\", nestedSessionTenancyBlocker(error), {\n cause: error,\n });\n }\n if (state === \"40001\" && options.authorityEpochConflict) {\n throw new SessionTenancyConflictError(\"authority_epoch\", null, { cause: error });\n }\n if (state === \"23505\") {\n throw new SessionTenancyConflictError(\"operation_reuse\", null, { cause: error });\n }\n if (state === \"55000\") {\n throw new SessionTenancyNotActivatedError({ cause: error });\n }\n if (state === \"42501\" || state === \"P0002\") {\n throw new SessionTenancyAccessError({ cause: error });\n }\n if (state === \"22023\") {\n throw new SessionTenancyInvalidRequestError({ cause: error });\n }\n throw error;\n}\n\nexport function canonicalSessionVisibilityTransitionHash(\n input: Pick<\n TransitionSessionVisibilityInput,\n \"sessionId\" | \"targetVisibility\" | \"expectedAuthorityEpoch\"\n >,\n): string {\n return createHash(\"sha256\")\n .update(\n JSON.stringify({\n version: 1,\n sessionId: input.sessionId,\n targetVisibility: input.targetVisibility,\n expectedAuthorityEpoch: input.expectedAuthorityEpoch,\n }),\n )\n .digest(\"hex\");\n}\n\nexport function canonicalSessionForkHash(\n input: Pick<\n ForkSessionContentInput,\n | \"sourceSessionId\"\n | \"destinationWorkspaceId\"\n | \"destinationVisibility\"\n | \"workspaceSharedAcknowledged\"\n | \"runtimeRequest\"\n | \"sourceEventId\"\n >,\n): string {\n if (input.sourceEventId) {\n return createHash(\"sha256\")\n .update(\n JSON.stringify({\n version: 4,\n sourceSessionId: input.sourceSessionId,\n destinationWorkspaceId: input.destinationWorkspaceId,\n destinationVisibility: input.destinationVisibility,\n workspaceSharedAcknowledged: input.workspaceSharedAcknowledged,\n sourceEventId: input.sourceEventId,\n }),\n )\n .digest(\"hex\");\n }\n if (input.runtimeRequest) {\n return createHash(\"sha256\")\n .update(\n JSON.stringify({\n version: 3,\n sourceSessionId: input.sourceSessionId,\n destinationWorkspaceId: input.destinationWorkspaceId,\n destinationVisibility: input.destinationVisibility,\n workspaceSharedAcknowledged: input.workspaceSharedAcknowledged,\n runtime: input.runtimeRequest,\n }),\n )\n .digest(\"hex\");\n }\n const legacyCompatiblePrivateRequest =\n input.destinationVisibility === \"user_private\" && !input.workspaceSharedAcknowledged;\n return createHash(\"sha256\")\n .update(\n JSON.stringify(\n legacyCompatiblePrivateRequest\n ? {\n version: 1,\n sourceSessionId: input.sourceSessionId,\n destinationWorkspaceId: input.destinationWorkspaceId,\n destinationVisibility: input.destinationVisibility,\n }\n : {\n version: 2,\n sourceSessionId: input.sourceSessionId,\n destinationWorkspaceId: input.destinationWorkspaceId,\n destinationVisibility: input.destinationVisibility,\n workspaceSharedAcknowledged: input.workspaceSharedAcknowledged,\n },\n ),\n )\n .digest(\"hex\");\n}\n\nfunction canonicalForkRuntimeConfigurationDigest(input: ForkSessionRuntimeRequest): string {\n return createHash(\"sha256\")\n .update(JSON.stringify({ version: 1, ...input }))\n .digest(\"hex\");\n}\n\nexport async function transitionSessionVisibility(\n db: Database,\n input: TransitionSessionVisibilityInput,\n): Promise<TransitionSessionVisibilityResult> {\n if (!Number.isSafeInteger(input.expectedAuthorityEpoch) || input.expectedAuthorityEpoch < 1) {\n throw new Error(\"expectedAuthorityEpoch must be a positive safe integer\");\n }\n if (!input.operationKey.trim()) throw new Error(\"operationKey must not be empty\");\n const requestHash = canonicalSessionVisibilityTransitionHash(input);\n const { accountId } = await rlsContextForWorkspace(db, input.workspaceId);\n try {\n return await withWorkspaceSubjectSessionActivityRls(\n db,\n input.workspaceId,\n input.actorSubjectId,\n async (scopedDb) => {\n const rows = await rawRows<{\n operationId: string;\n eventId: string | null;\n eventSequence: number | null;\n visibility: SessionTenancyVisibility;\n authorityEpoch: number;\n ownerOrganizationMembershipId: string | null;\n changed: boolean;\n replay: boolean;\n interruptedAttemptCount: number;\n cancelledTurnCount: number;\n cancelledUpdateCount: number;\n pausedGoalCount: number;\n revokedGrantCount: number;\n }>(\n scopedDb,\n sql`select\n operation_id as \"operationId\",\n event_id as \"eventId\",\n event_sequence as \"eventSequence\",\n visibility,\n authority_epoch as \"authorityEpoch\",\n owner_organization_membership_id as \"ownerOrganizationMembershipId\",\n changed,\n replay,\n interrupted_attempt_count as \"interruptedAttemptCount\",\n cancelled_turn_count as \"cancelledTurnCount\",\n cancelled_update_count as \"cancelledUpdateCount\",\n paused_goal_count as \"pausedGoalCount\",\n revoked_grant_count as \"revokedGrantCount\"\n from transition_session_visibility(\n ${accountId}::uuid,\n ${input.workspaceId}::uuid,\n ${input.sessionId}::uuid,\n ${input.actorSubjectId},\n ${input.targetVisibility},\n ${input.expectedAuthorityEpoch},\n ${input.operationKey},\n ${requestHash},\n ${SESSION_TENANCY_ACTIVATION_VERSION}\n )`,\n );\n const result = rows[0];\n if (!result) throw new Error(\"Session visibility transition returned no result\");\n await input.beforeCommit?.(scopedDb);\n return result;\n },\n undefined,\n \"none\",\n );\n } catch (error) {\n mapSessionTenancyPersistenceError(error, { authorityEpochConflict: true });\n }\n}\n\nexport async function forkSessionContent(\n db: Database,\n input: ForkSessionContentInput,\n): Promise<ForkSessionContentResult> {\n if (!input.operationKey.trim()) throw new Error(\"operationKey must not be empty\");\n if (input.destinationWorkspaceId !== input.sourceWorkspaceId) {\n throw new Error(\"The first session fork contract is same-workspace only\");\n }\n if (input.sourceEventId && input.runtimeRequest) {\n throw new Error(\"Message forks cannot replace runtime setup\");\n }\n if (Boolean(input.runtimeRequest) !== Boolean(input.runtimeConfiguration)) {\n throw new Error(\"A fresh session fork runtime request requires its resolved configuration\");\n }\n if (\n input.runtimeRequest &&\n (input.runtimeRequest.rigId !== input.runtimeConfiguration?.rigId ||\n JSON.stringify(input.runtimeRequest.variableSetIds) !==\n JSON.stringify(input.runtimeConfiguration?.variableSetIds))\n ) {\n throw new Error(\"Resolved session fork runtime configuration does not match its request\");\n }\n const { accountId } = await rlsContextForWorkspace(db, input.sourceWorkspaceId);\n const requestHash = canonicalSessionForkHash(input);\n try {\n return await withWorkspaceSubjectRls(\n db,\n input.sourceWorkspaceId,\n input.actorSubjectId,\n async (scopedDb) => {\n if (input.runtimeRequest && input.runtimeConfiguration) {\n const runtimeDigest = canonicalForkRuntimeConfigurationDigest(input.runtimeRequest);\n const rows = await rawRows<ForkSessionContentResult>(\n scopedDb,\n sql`select\n operation_id as \"operationId\",\n event_id as \"eventId\",\n event_sequence as \"eventSequence\",\n session_id as \"sessionId\",\n workspace_id as \"workspaceId\",\n visibility,\n authority_epoch as \"authorityEpoch\",\n copied_history_item_count as \"copiedHistoryItemCount\",\n replay,\n runtime_event_id as \"runtimeEventId\",\n runtime_event_sequence as \"runtimeEventSequence\"\n from fork_session_content_with_runtime(\n ${accountId}::uuid,\n ${input.sourceWorkspaceId}::uuid,\n ${input.sourceSessionId}::uuid,\n ${input.actorSubjectId},\n ${input.destinationWorkspaceId}::uuid,\n ${input.destinationVisibility},\n ${input.workspaceSharedAcknowledged},\n ${input.operationKey},\n ${requestHash},\n ${SESSION_TENANCY_ACTIVATION_VERSION},\n ${JSON.stringify(input.runtimeConfiguration.variableSetIds)}::jsonb,\n ${input.runtimeConfiguration.rigId}::uuid,\n ${input.runtimeConfiguration.rigVersionId}::uuid,\n ${runtimeDigest}\n )`,\n );\n const result = rows[0];\n if (!result) throw new Error(\"Session fork returned no result\");\n await input.beforeCommit?.(scopedDb);\n return result;\n }\n const rows = await rawRows<ForkSessionContentResult>(\n scopedDb,\n sql`select\n operation_id as \"operationId\",\n event_id as \"eventId\",\n event_sequence as \"eventSequence\",\n session_id as \"sessionId\",\n workspace_id as \"workspaceId\",\n visibility,\n authority_epoch as \"authorityEpoch\",\n copied_history_item_count as \"copiedHistoryItemCount\",\n replay,\n null::uuid as \"runtimeEventId\",\n null::integer as \"runtimeEventSequence\"\n from fork_session_content(\n ${accountId}::uuid,\n ${input.sourceWorkspaceId}::uuid,\n ${input.sourceSessionId}::uuid,\n ${input.actorSubjectId},\n ${input.destinationWorkspaceId}::uuid,\n ${input.destinationVisibility},\n ${input.workspaceSharedAcknowledged},\n ${input.operationKey},\n ${requestHash},\n ${SESSION_TENANCY_ACTIVATION_VERSION}\n ${input.sourceEventId ? sql`, ${input.sourceEventId}::uuid` : sql``}\n )`,\n );\n const result = rows[0];\n if (!result) throw new Error(\"Session fork returned no result\");\n await input.beforeCommit?.(scopedDb);\n return result;\n },\n undefined,\n \"none\",\n );\n } catch (error) {\n // A private destination inside a shared workspace carries the same\n // organization owner/admin product decision the create path enforces\n // (migration 0323), and the fork routine raises the same 55000. Surface it\n // as the not-activated product state rather than an opaque database error.\n if (nestedPostgresSqlState(error) === \"55000\") {\n throw new SessionTenancyNotActivatedError({ cause: error });\n }\n mapSessionTenancyPersistenceError(error, { authorityEpochConflict: false });\n }\n}\n\n/**\n * Recover one exact committed fork before mutable source-session authorization.\n *\n * The database capability requires the authenticated actor's active workspace\n * authority and matches the complete actor/workspace/source/key/request-hash\n * tuple. A fresh key returns null; changed intent raises the ordinary tenancy\n * idempotency conflict. This is receipt recovery, not session discovery.\n */\nexport async function replayAppliedSessionFork(\n db: Database,\n input: ForkSessionContentInput,\n): Promise<ForkSessionContentResult | null> {\n if (!input.operationKey.trim()) throw new Error(\"operationKey must not be empty\");\n if (input.destinationWorkspaceId !== input.sourceWorkspaceId) {\n throw new Error(\"The first session fork contract is same-workspace only\");\n }\n const { accountId } = await rlsContextForWorkspace(db, input.sourceWorkspaceId);\n const requestHash = canonicalSessionForkHash(input);\n try {\n return await withWorkspaceSubjectRls(\n db,\n input.sourceWorkspaceId,\n input.actorSubjectId,\n async (scopedDb) => {\n if (input.runtimeRequest) {\n const runtimeDigest = canonicalForkRuntimeConfigurationDigest(input.runtimeRequest);\n const rows = await rawRows<ForkSessionContentResult>(\n scopedDb,\n sql`select\n operation_id as \"operationId\",\n event_id as \"eventId\",\n event_sequence as \"eventSequence\",\n session_id as \"sessionId\",\n workspace_id as \"workspaceId\",\n visibility,\n authority_epoch as \"authorityEpoch\",\n copied_history_item_count as \"copiedHistoryItemCount\",\n replay,\n runtime_event_id as \"runtimeEventId\",\n runtime_event_sequence as \"runtimeEventSequence\"\n from replay_applied_session_fork_with_runtime(\n ${accountId}::uuid,\n ${input.sourceWorkspaceId}::uuid,\n ${input.sourceSessionId}::uuid,\n ${input.actorSubjectId},\n ${input.destinationWorkspaceId}::uuid,\n ${input.destinationVisibility},\n ${input.workspaceSharedAcknowledged},\n ${input.operationKey},\n ${requestHash},\n ${SESSION_TENANCY_ACTIVATION_VERSION},\n ${runtimeDigest}\n )`,\n );\n await input.beforeCommit?.(scopedDb);\n return rows[0] ?? null;\n }\n const rows = await rawRows<ForkSessionContentResult>(\n scopedDb,\n sql`select\n operation_id as \"operationId\",\n event_id as \"eventId\",\n event_sequence as \"eventSequence\",\n session_id as \"sessionId\",\n workspace_id as \"workspaceId\",\n visibility,\n authority_epoch as \"authorityEpoch\",\n copied_history_item_count as \"copiedHistoryItemCount\",\n replay,\n null::uuid as \"runtimeEventId\",\n null::integer as \"runtimeEventSequence\"\n from replay_applied_session_fork(\n ${accountId}::uuid,\n ${input.sourceWorkspaceId}::uuid,\n ${input.sourceSessionId}::uuid,\n ${input.actorSubjectId},\n ${input.destinationWorkspaceId}::uuid,\n ${input.destinationVisibility},\n ${input.workspaceSharedAcknowledged},\n ${input.operationKey},\n ${requestHash},\n ${SESSION_TENANCY_ACTIVATION_VERSION}\n )`,\n );\n await input.beforeCommit?.(scopedDb);\n return rows[0] ?? null;\n },\n );\n } catch (error) {\n mapSessionTenancyPersistenceError(error, { authorityEpochConflict: false });\n }\n}\n"],"mappings":"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","names":["rows","result"]}
@@ -7,9 +7,9 @@ import {
7
7
  getConnectAttempt,
8
8
  getConnectBeginReplay,
9
9
  listPendingConnectAttempts
10
- } from "./chunk-OQZOGCLG.js";
11
- import "./chunk-56MYWKQV.js";
12
- import "./chunk-LDTQGYD2.js";
10
+ } from "./chunk-BLUQG54M.js";
11
+ import "./chunk-SKYRM7R7.js";
12
+ import "./chunk-VOB6TXSJ.js";
13
13
  import "./chunk-P7YDM2RI.js";
14
14
  import "./chunk-PZ5AY32C.js";
15
15
  export {
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  rawRows,
3
3
  withRlsContext
4
- } from "./chunk-56MYWKQV.js";
5
- import "./chunk-LDTQGYD2.js";
4
+ } from "./chunk-SKYRM7R7.js";
5
+ import "./chunk-VOB6TXSJ.js";
6
6
  import "./chunk-P7YDM2RI.js";
7
7
  import "./chunk-PZ5AY32C.js";
8
8
 
@@ -10,9 +10,9 @@ import {
10
10
  listEditableArtifactIdsForSession,
11
11
  touchEditableArtifactSessionLink,
12
12
  transactionallyAuthorizeEditableArtifactActor
13
- } from "./chunk-Y77PVZZD.js";
14
- import "./chunk-56MYWKQV.js";
15
- import "./chunk-LDTQGYD2.js";
13
+ } from "./chunk-BZV5ZDRY.js";
14
+ import "./chunk-SKYRM7R7.js";
15
+ import "./chunk-VOB6TXSJ.js";
16
16
  import "./chunk-P7YDM2RI.js";
17
17
  import "./chunk-PZ5AY32C.js";
18
18
  export {
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { SubscriptionAccountChangedError } from "./subscription-account-conflict.js";
2
+ import type { GoalAdmissionPausedReason } from "@opengeni/contracts";
2
3
  export declare const getScheduledTaskClaudeProviderAccountAuthoritySnapshot: (db: Database, workspaceId: string, taskId: string) => Promise<{
3
4
  version: 1;
4
5
  scope: "organization";
@@ -3306,7 +3307,7 @@ export declare function recordScheduledTaskAdmissionFailure(db: Database, input:
3306
3307
  diagnostic: ConnectionAccountSelectionDiagnostic;
3307
3308
  }): Promise<ScheduledTaskRun>;
3308
3309
  /** Reasons a scheduled occurrence is refused before accepting execution. */
3309
- export type ScheduledTaskAdmissionRefusalReason = "scheduled_authority_unavailable" | "machine_target_unavailable" | "machine_enrollment_inactive" | "variable_set_unavailable" | "rig_version_unavailable" | "insufficient_credits" | "allowance_exhausted" | "monthly_model_cost_limit" | "monthly_agent_run_limit";
3310
+ export type ScheduledTaskAdmissionRefusalReason = "scheduled_authority_unavailable" | "machine_target_unavailable" | "machine_enrollment_inactive" | "variable_set_unavailable" | "rig_version_unavailable" | "scheduled_model_unavailable" | "insufficient_credits" | "allowance_exhausted" | "monthly_model_cost_limit" | "monthly_agent_run_limit";
3310
3311
  /**
3311
3312
  * Record a refused occurrence as an immutable run receipt under its producer
3312
3313
  * identity (migration 0539). A transient refusal is `skipped`, a terminal one
@@ -10400,6 +10401,11 @@ export declare function updateSessionTitleWithEvent(db: Database, input: {
10400
10401
  title: string | null;
10401
10402
  events: SessionEvent[];
10402
10403
  }>;
10404
+ /** Read-only admission at a locked paused-to-active transition. */
10405
+ export type SessionGoalResumeValidation = (tx: Database, session: Pick<Session, "accountId" | "workspaceId" | "model" | "codexCompactionMode" | "latencyMode">, causalTurn: {
10406
+ id: string;
10407
+ initiatingHumanSubjectId: string | null;
10408
+ } | null) => Promise<void>;
10403
10409
  /**
10404
10410
  * Status transition helper. Idempotent: requesting the current status returns
10405
10411
  * `changed: false` so callers can skip emitting a duplicate event. `completed`
@@ -10417,6 +10423,8 @@ export declare function setSessionGoalStatus(db: Database, workspaceId: string,
10417
10423
  commandActor?: Extract<SessionCommandActor, {
10418
10424
  type: "agent_attempt";
10419
10425
  }>;
10426
+ /** Runs under the canonical control/session/goal locks, before a paused goal changes. */
10427
+ beforeResume?: SessionGoalResumeValidation;
10420
10428
  }): Promise<{
10421
10429
  goal: SessionGoal;
10422
10430
  changed: boolean;
@@ -10445,6 +10453,7 @@ export declare function setSessionGoalStatusWithEvent(db: Database, workspaceId:
10445
10453
  commandActor?: Extract<SessionCommandActor, {
10446
10454
  type: "agent_attempt";
10447
10455
  }>;
10456
+ beforeResume?: SessionGoalResumeValidation;
10448
10457
  event: SetSessionGoalStatusEvent;
10449
10458
  }): Promise<{
10450
10459
  goal: SessionGoal;
@@ -10459,7 +10468,7 @@ export type GoalContinuationDecision = {
10459
10468
  decision: "queue";
10460
10469
  } | {
10461
10470
  decision: "paused";
10462
- reason: "max_auto_continuations" | "limits" | "allowance";
10471
+ reason: "max_auto_continuations" | "limits" | GoalAdmissionPausedReason;
10463
10472
  goal: SessionGoal;
10464
10473
  } | {
10465
10474
  decision: "continue";
@@ -10479,7 +10488,7 @@ export declare function evaluateGoalContinuation(db: Database, input: {
10479
10488
  sessionId: string;
10480
10489
  defaultMaxAutoContinuations?: number | null;
10481
10490
  budgetBlocked?: string | null;
10482
- budgetPausedReason?: "limits" | "allowance" | undefined;
10491
+ budgetPausedReason?: "limits" | GoalAdmissionPausedReason | undefined;
10483
10492
  }): Promise<GoalContinuationDecision>;
10484
10493
  export declare const GOAL_IDLE_BACKOFF_WAKE_REASON = "goal_idle_backoff";
10485
10494
  /**
@@ -10526,7 +10535,7 @@ export declare function materializeGoalContinuation(db: Database, input: {
10526
10535
  workflowId: string;
10527
10536
  defaultMaxAutoContinuations?: number | null;
10528
10537
  budgetBlocked?: string | null;
10529
- budgetPausedReason?: "limits" | "allowance" | undefined;
10538
+ budgetPausedReason?: "limits" | GoalAdmissionPausedReason | undefined;
10530
10539
  /** Trusted worker admission, evaluated under the same session/goal locks
10531
10540
  * as lineage materialization. Never substitutes a mutable latest human. */
10532
10541
  admission?: (tx: Database, causalTurn: {
@@ -10534,7 +10543,7 @@ export declare function materializeGoalContinuation(db: Database, input: {
10534
10543
  initiatingHumanSubjectId: string | null;
10535
10544
  } | null) => Promise<{
10536
10545
  budgetBlocked: string | null;
10537
- budgetPausedReason?: "limits" | "allowance";
10546
+ budgetPausedReason?: "limits" | GoalAdmissionPausedReason;
10538
10547
  }>;
10539
10548
  idleBackoff?: GoalIdleBackoffPolicy | null;
10540
10549
  policy: {
package/dist/index.js CHANGED
@@ -8,14 +8,15 @@ import {
8
8
  normalizeBearerScheme,
9
9
  normalizedCredentialHeaders,
10
10
  refreshOAuthConnectionCredential
11
- } from "./chunk-7POTLB24.js";
11
+ } from "./chunk-M2YGXCCQ.js";
12
12
  import {
13
13
  retainedProviderCommandPersistence
14
- } from "./chunk-OMHBVHX7.js";
14
+ } from "./chunk-ODKYBA3C.js";
15
15
  import {
16
16
  readSessionMessageSliceInScope
17
- } from "./chunk-NLSG7GGA.js";
17
+ } from "./chunk-KJVOBLFC.js";
18
18
  import {
19
+ ARTIFACT_PIN_RUNTIME_ROUTINES,
19
20
  CLAUDE_SUBSCRIPTION_CAPABILITY_ROUTINES,
20
21
  FORCE_RLS_TABLES,
21
22
  NON_RLS_RUNTIME_TABLES,
@@ -45,7 +46,7 @@ import {
45
46
  isRetryableRuntimeDatabaseStartupError,
46
47
  provisionRoles,
47
48
  runtimeDatabaseReadyCheck
48
- } from "./chunk-N5QCKHYL.js";
49
+ } from "./chunk-T5NHDEZW.js";
49
50
  import {
50
51
  CanonicalHumanIdentityAuthorityError,
51
52
  CanonicalHumanIdentityConflictError,
@@ -59,7 +60,7 @@ import {
59
60
  getCanonicalHumanIdentityProjection,
60
61
  synchronizeCanonicalHumanLoginBindings,
61
62
  validateCanonicalHumanSession
62
- } from "./chunk-KEDWSSNP.js";
63
+ } from "./chunk-7Z7ALFRE.js";
63
64
  import {
64
65
  EDITABLE_ARTIFACT_INTENT_MAX_BYTES,
65
66
  EDITABLE_ARTIFACT_KERNEL_TAIL_MAX_BYTES,
@@ -72,7 +73,7 @@ import {
72
73
  listEditableArtifactIdsForSession,
73
74
  touchEditableArtifactSessionLink,
74
75
  transactionallyAuthorizeEditableArtifactActor
75
- } from "./chunk-Y77PVZZD.js";
76
+ } from "./chunk-BZV5ZDRY.js";
76
77
  import {
77
78
  SessionTenancyAccessError,
78
79
  SessionTenancyConflictError,
@@ -87,10 +88,9 @@ import {
87
88
  openPrivateChildSessionCreateCapability,
88
89
  openPrivateSessionCreateCapability,
89
90
  replayAppliedSessionFork,
90
- sessionTenancyProductActivated,
91
91
  transitionSessionVisibility
92
- } from "./chunk-UEQQ2WWU.js";
93
- import "./chunk-F3YMVRF4.js";
92
+ } from "./chunk-Z5HJXH3X.js";
93
+ import "./chunk-GLA5YCQS.js";
94
94
  import {
95
95
  ConnectAttemptConflictError,
96
96
  ConnectAttemptNotFoundError,
@@ -100,11 +100,11 @@ import {
100
100
  getConnectAttempt,
101
101
  getConnectBeginReplay,
102
102
  listPendingConnectAttempts
103
- } from "./chunk-OQZOGCLG.js";
103
+ } from "./chunk-BLUQG54M.js";
104
104
  import {
105
105
  withOrganizationIntegrationAcquisition,
106
106
  withOrganizationIntegrationPolicyFence
107
- } from "./chunk-PQGTWFRF.js";
107
+ } from "./chunk-M3SWH4MU.js";
108
108
  import {
109
109
  AgentCommandAuthorityError,
110
110
  CHILD_LIFECYCLE_DEDUPE_PREFIX,
@@ -254,7 +254,7 @@ import {
254
254
  validateOrganizationApiKeyWorkspaceScope,
255
255
  workspaceControlLockBudget,
256
256
  workspaceControlRequestLockTimeoutMs
257
- } from "./chunk-7S53WLPI.js";
257
+ } from "./chunk-EKXCF3FH.js";
258
258
  import {
259
259
  ACTIVE_VIDEO_GENERATION_STATUSES,
260
260
  CreditDebitAttribution,
@@ -304,7 +304,7 @@ import {
304
304
  validateMemberAllowanceRule,
305
305
  validateWorkspaceAllowanceConfig,
306
306
  withCreditDebitAttribution
307
- } from "./chunk-MACELCXG.js";
307
+ } from "./chunk-CIGHXFPD.js";
308
308
  import {
309
309
  external_exports
310
310
  } from "./chunk-4UJCXBR2.js";
@@ -330,7 +330,7 @@ import {
330
330
  reapManagedAuthIsolatedSessions,
331
331
  releaseManagedAuthActorMutationLease,
332
332
  validateManagedAuthActorMutationLease
333
- } from "./chunk-KH3TYDGY.js";
333
+ } from "./chunk-J4WFOVBV.js";
334
334
  import {
335
335
  SandboxProviderReadLockUnavailableError,
336
336
  SessionEventPersistenceError,
@@ -369,7 +369,7 @@ import {
369
369
  withWorkspaceSubjectRls,
370
370
  withWorkspaceSubjectSessionActivityRls,
371
371
  withWorkspaceUsageLock
372
- } from "./chunk-56MYWKQV.js";
372
+ } from "./chunk-SKYRM7R7.js";
373
373
  import {
374
374
  agentRunStates,
375
375
  apiKeys,
@@ -618,7 +618,7 @@ import {
618
618
  xaiRotationSettings,
619
619
  xaiSessionAccountPins,
620
620
  xaiSubscriptionCredentials
621
- } from "./chunk-LDTQGYD2.js";
621
+ } from "./chunk-VOB6TXSJ.js";
622
622
  import {
623
623
  decryptEnvironmentValue,
624
624
  encryptEnvironmentValue,
@@ -4855,6 +4855,13 @@ async function scanSessionMessages(db, workspaceId, request, filters, authorityI
4855
4855
 
4856
4856
  // src/artifact-catalog.ts
4857
4857
  import { sql as sql17 } from "drizzle-orm";
4858
+ async function updateArtifactPin(db, scope, input) {
4859
+ await withRlsContext(db, scope, async (tx) => {
4860
+ await tx.execute(sql17`select opengeni_private.update_artifact_pin(
4861
+ ${scope.accountId}::uuid, ${scope.workspaceId}::uuid,
4862
+ ${input.kind}::text, ${input.artifactId}::text, ${input.pinned}::boolean)`);
4863
+ });
4864
+ }
4858
4865
  async function recordSandboxFilePublication(db, input) {
4859
4866
  await withRlsContext(db, input, async (tx) => {
4860
4867
  await tx.execute(
@@ -4903,26 +4910,30 @@ async function listArtifactCatalogCandidates(db, scope, input) {
4903
4910
  branches.push(sql17`
4904
4911
  SELECT p.file_id::text AS id, p.kind, p.title, 'active'::text AS status,
4905
4912
  p.published_at AS created_at, p.published_at AS updated_at, p.source_session_id, NULL::text AS version_id, 'sandbox_file'::text AS origin
4906
- FROM opengeni_private.list_sandbox_file_publications(${scope.accountId}::uuid, ${scope.workspaceId}::uuid,
4913
+ FROM opengeni_private.list_sandbox_file_publications_pinned(${scope.accountId}::uuid, ${scope.workspaceId}::uuid,
4907
4914
  ${JSON.stringify({ sourceSessionId: source, q: query.q, kinds: publishedKinds, sort: query.sort, snapshotAt: input.snapshotAt, after: input.after, limit: input.limit })}::jsonb) p`);
4908
4915
  if (!branches.length) return [];
4909
4916
  const sort = query.sort === "title" ? sql17`lower(title)` : query.sort === "newest" ? sql17`to_char(created_at AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.US')` : sql17`to_char(updated_at AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.US')`;
4910
4917
  const descending = query.sort !== "title";
4911
4918
  const position = input.after;
4912
- const keyset = !position ? sql17`true` : sql17`(
4919
+ const secondaryKeyset = !position ? sql17`true` : sql17`(
4913
4920
  sort_key COLLATE "C" ${descending ? sql17`<` : sql17`>`} ${position.key} COLLATE "C"
4914
4921
  OR (sort_key = ${position.key} AND (kind COLLATE "C", id COLLATE "C") > (${position.kind}, ${position.id})))`;
4922
+ const keyset = !position ? sql17`true` : sql17`(pinned < ${position.pinned ?? false}::boolean OR
4923
+ (pinned = ${position.pinned ?? false}::boolean AND ${secondaryKeyset}))`;
4915
4924
  return withRlsContext(
4916
4925
  db,
4917
4926
  scope,
4918
4927
  async (tx) => {
4919
4928
  const result = await tx.execute(sql17`
4920
4929
  WITH candidates AS (${sql17.join(branches, sql17` UNION ALL `)}),
4921
- ordered AS (SELECT *, ${sort} AS sort_key FROM candidates
4930
+ ordered AS (SELECT candidates.*, ${sort} AS sort_key, (pins.artifact_id IS NOT NULL) AS pinned
4931
+ FROM candidates LEFT JOIN opengeni_private.list_artifact_pins(${scope.accountId}::uuid, ${scope.workspaceId}::uuid) pins
4932
+ ON pins.kind = candidates.kind AND pins.artifact_id = candidates.id
4922
4933
  WHERE status = ${query.status} AND created_at <= ${input.snapshotAt}::timestamptz
4923
4934
  ${query.q ? sql17`AND strpos(lower(title), lower(${query.q})) > 0` : sql17``})
4924
4935
  SELECT * FROM ordered WHERE ${keyset}
4925
- ORDER BY sort_key COLLATE "C" ${descending ? sql17`DESC` : sql17`ASC`}, kind COLLATE "C", id COLLATE "C"
4936
+ ORDER BY pinned DESC, sort_key COLLATE "C" ${descending ? sql17`DESC` : sql17`ASC`}, kind COLLATE "C", id COLLATE "C"
4926
4937
  LIMIT ${input.limit}`);
4927
4938
  return Array.isArray(result) ? result : result.rows;
4928
4939
  },
@@ -69399,10 +69410,6 @@ async function readSessionListForSubject(db, workspaceId, options, summary) {
69399
69410
  }))) {
69400
69411
  throw new SessionListAccessError();
69401
69412
  }
69402
- const tenancyActivated = await sessionTenancyProductActivated(
69403
- tx,
69404
- workspaceId
69405
- );
69406
69413
  const archiveMode = options.archiveStatus ?? (options.archivedOnly ? "archived" : "active");
69407
69414
  const sortBy = options.sortBy ?? (archiveMode === "archived" ? "archivedAt" : "updatedAt");
69408
69415
  if (options.archivedOnly && archiveMode !== "archived") {
@@ -69718,7 +69725,7 @@ async function readSessionListForSubject(db, workspaceId, options, summary) {
69718
69725
  ...mapSessionArchive(row.pin),
69719
69726
  ...row.pin?.archived && exactArchiveTimestamps.has(session.id) ? { archivedAt: exactArchiveTimestamps.get(session.id) } : {}
69720
69727
  },
69721
- { subjectId: options.subjectId, activated: tenancyActivated }
69728
+ { subjectId: options.subjectId }
69722
69729
  ),
69723
69730
  ...sortBy === "updatedAt" && exactOrdinaryTimestamps.has(session.id) ? { updatedAt: exactOrdinaryTimestamps.get(session.id) } : {},
69724
69731
  ...sortBy === "createdAt" && exactOrdinaryTimestamps.has(session.id) ? { createdAt: exactOrdinaryTimestamps.get(session.id) } : {},
@@ -69899,7 +69906,6 @@ async function getSessionForSubject(db, workspaceId, sessionId, subjectId, relat
69899
69906
  const mcpServers = await sessionMcpServerMetadataForSessions(scopedDb, workspaceId, [
69900
69907
  sessionId
69901
69908
  ]);
69902
- const tenancyActivated = await sessionTenancyProductActivated(scopedDb, workspaceId);
69903
69909
  const failureDiagnostics = await sessionFailureDiagnostics(scopedDb, workspaceId, session);
69904
69910
  return projectSessionForRelatedAccess(
69905
69911
  {
@@ -69911,7 +69917,7 @@ async function getSessionForSubject(db, workspaceId, sessionId, subjectId, relat
69911
69917
  mapSessionAttention(session, row.pin),
69912
69918
  mapSessionArchive(row.pin),
69913
69919
  void 0,
69914
- { subjectId, activated: tenancyActivated }
69920
+ { subjectId }
69915
69921
  ),
69916
69922
  failureDiagnostics
69917
69923
  },
@@ -73987,6 +73993,13 @@ async function applyContextCompaction(db, input) {
73987
73993
  )
73988
73994
  );
73989
73995
  const supersededFrom = Math.floor(Number(maxPosition)) + 1;
73996
+ if (providerRecoveryCountFromTurnMetadata(fence.turn.metadata) > 0) {
73997
+ await tx.update(sessionTurns).set({
73998
+ metadata: metadataWithoutProviderRecoveryCount(fence.turn.metadata),
73999
+ version: fence.turn.version + 1,
74000
+ updatedAt: /* @__PURE__ */ new Date()
74001
+ }).where(eq74(sessionTurns.id, input.turnId));
74002
+ }
73990
74003
  await tx.update(sessionHistoryItems).set({ active: false }).where(
73991
74004
  and73(
73992
74005
  eq74(sessionHistoryItems.workspaceId, input.workspaceId),
@@ -88364,6 +88377,40 @@ async function setSessionGoalStatus(db, workspaceId, sessionId, input) {
88364
88377
  if (existing.status === "completed") {
88365
88378
  throw new Error("session goal is completed; set a new goal to continue");
88366
88379
  }
88380
+ if (input.status === "active" && input.beforeResume) {
88381
+ const [effectiveSession] = await withEffectiveSessionPolicy(scopedDb, workspaceId, [session]);
88382
+ const causalTurnFilter = session.activeTurnId ? or12(
88383
+ eq74(sessionTurns.id, session.activeTurnId),
88384
+ sql108`${sessionTurns.finishedAt} is not null`
88385
+ ) : sql108`${sessionTurns.finishedAt} is not null`;
88386
+ const [causalTurn] = await scopedDb.select({
88387
+ id: sessionTurns.id,
88388
+ initiatingHumanSubjectId: sessionTurns.initiatingHumanSubjectId
88389
+ }).from(sessionTurns).where(
88390
+ and73(
88391
+ eq74(sessionTurns.workspaceId, workspaceId),
88392
+ eq74(sessionTurns.sessionId, sessionId),
88393
+ causalTurnFilter
88394
+ )
88395
+ ).orderBy(
88396
+ ...session.activeTurnId ? [desc27(sql108`${sessionTurns.id} = ${session.activeTurnId}`)] : [],
88397
+ desc27(sessionTurns.finishedAt),
88398
+ desc27(sessionTurns.position),
88399
+ desc27(sessionTurns.createdAt),
88400
+ desc27(sessionTurns.id)
88401
+ ).limit(1);
88402
+ await input.beforeResume(
88403
+ scopedDb,
88404
+ {
88405
+ accountId: session.accountId,
88406
+ workspaceId,
88407
+ model: effectiveSession.model,
88408
+ latencyMode: effectiveSession.latencyMode,
88409
+ codexCompactionMode: session.codexCompactionMode
88410
+ },
88411
+ causalTurn ?? null
88412
+ );
88413
+ }
88367
88414
  if (input.status === "completed") {
88368
88415
  await verifyGoalReportDeliveries(scopedDb, {
88369
88416
  accountId: session.accountId,
@@ -88441,6 +88488,7 @@ async function setSessionGoalStatusWithEvent(db, workspaceId, sessionId, input)
88441
88488
  ...input.reportDeliveries !== void 0 ? { reportDeliveries: input.reportDeliveries } : {},
88442
88489
  ...input.reportArtifactActor ? { reportArtifactActor: input.reportArtifactActor } : {},
88443
88490
  ...input.commandActor ? { commandActor: input.commandActor } : {},
88491
+ ...input.beforeResume ? { beforeResume: input.beforeResume } : {},
88444
88492
  ...input.evidence !== void 0 ? { evidence: input.evidence } : {},
88445
88493
  ...input.rationale !== void 0 ? { rationale: input.rationale } : {},
88446
88494
  ...input.pausedReason !== void 0 ? { pausedReason: input.pausedReason } : {}
@@ -95535,6 +95583,8 @@ function providerRecoveryCountFromTurnMetadata(metadata) {
95535
95583
  function metadataWithoutProviderRecoveryCount(metadata) {
95536
95584
  const next = { ...metadata ?? {} };
95537
95585
  delete next.providerRecoveryCount;
95586
+ delete next.providerRecoveryStartedAt;
95587
+ delete next.providerRecoveryReason;
95538
95588
  return next;
95539
95589
  }
95540
95590
  function hasCompletedCurrentModelRequest(events, requireMeaningfulOutput = false) {
@@ -97216,7 +97266,11 @@ async function requestSessionTurnRecovery(db, workspaceId, input) {
97216
97266
  providerRecoveryCount: SANDBOX_SETUP_RECOVERY_LIMIT
97217
97267
  }
97218
97268
  } : {},
97219
- ...input.providerRecoveryCount !== void 0 ? { providerRecoveryCount: input.providerRecoveryCount } : {}
97269
+ ...input.providerRecoveryCount !== void 0 ? {
97270
+ providerRecoveryCount: input.providerRecoveryCount,
97271
+ providerRecoveryStartedAt: providerRecoveryCountFromTurnMetadata(turn.metadata) > 0 && typeof turn.metadata?.providerRecoveryStartedAt === "string" ? turn.metadata.providerRecoveryStartedAt : now.toISOString(),
97272
+ providerRecoveryReason: input.reason
97273
+ } : {}
97220
97274
  },
97221
97275
  updatedAt: now
97222
97276
  }).where(
@@ -100854,7 +100908,7 @@ function mapSession(row, effectiveControl, mcpServers = [], pin = mapSessionPin(
100854
100908
  toolPolicyVersion: Number(row.toolPolicyVersion),
100855
100909
  mcpApprovalPolicies: row.mcpApprovalPolicies,
100856
100910
  metadata: row.metadata,
100857
- ...tenancyViewer?.activated ? { tenancy: mapSessionTenancy(row, tenancyViewer.subjectId) } : {},
100911
+ ...tenancyViewer ? { tenancy: mapSessionTenancy(row, tenancyViewer.subjectId) } : {},
100858
100912
  createdBy: initiatorFromStorage(
100859
100913
  row.createdByKind,
100860
100914
  row.createdBySubjectId,
@@ -101865,6 +101919,7 @@ export {
101865
101919
  APPROVAL_RUN_STATE_MAX_JSON_BYTES,
101866
101920
  APPROVAL_RUN_STATE_MAX_JSON_NODES,
101867
101921
  APPROVAL_RUN_STATE_MAX_JSON_PROPERTIES,
101922
+ ARTIFACT_PIN_RUNTIME_ROUTINES,
101868
101923
  ATTACHED_BROWSER_SESSION_CAPABILITIES,
101869
101924
  ActiveSessionHistoryLimitExceededError,
101870
101925
  AgentCommandAuthorityError,
@@ -103851,7 +103906,6 @@ export {
103851
103906
  sessionRequiresActionSinceForSessions,
103852
103907
  sessionSubject,
103853
103908
  sessionSystemUpdateOutboxKindPayload,
103854
- sessionTenancyProductActivated,
103855
103909
  sessionTreeStatsForSessions,
103856
103910
  sessionTurnFinalReplyFacts,
103857
103911
  sessionTurnHasFinalReplyNudge,
@@ -103973,6 +104027,7 @@ export {
103973
104027
  uninstallApiIntegration,
103974
104028
  uninstallPluginPackage,
103975
104029
  uninstallPortableSkill,
104030
+ updateArtifactPin,
103976
104031
  updateAutomationSource,
103977
104032
  updateAutomationTrigger,
103978
104033
  updateBrowserIdentity,