@opengeni/worker-bundle 2.0.3 → 2.1.0-canary.36239117573001

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 (51) hide show
  1. package/dist/activities/agent-turn/agent-build.d.ts +2 -0
  2. package/dist/activities/agent-turn/code-search.d.ts +60 -0
  3. package/dist/activities/agent-turn/codex-capacity.d.ts +13 -0
  4. package/dist/activities/agent-turn/errors.d.ts +12 -1
  5. package/dist/activities/agent-turn/governance-model.d.ts +2 -0
  6. package/dist/activities/agent-turn/session-title.d.ts +32 -2
  7. package/dist/activities/agent-turn/tool-environment.d.ts +4 -0
  8. package/dist/activities/context-compaction.d.ts +10 -2
  9. package/dist/activities/knowledge-indexing.d.ts +19 -0
  10. package/dist/{activities-control-IVTL723D.js → activities-control-I72CRMAE.js} +81 -14
  11. package/dist/activities-control-I72CRMAE.js.map +1 -0
  12. package/dist/{activities-turn-EZEDZTEZ.js → activities-turn-CSDKK4N3.js} +425 -46
  13. package/dist/activities-turn-CSDKK4N3.js.map +1 -0
  14. package/dist/artifact-outbox-entry.js +3 -0
  15. package/dist/artifact-outbox-entry.js.map +1 -1
  16. package/dist/{chunk-JMO5ZUW3.js → chunk-7M6G2SCF.js} +159 -11
  17. package/dist/chunk-7M6G2SCF.js.map +1 -0
  18. package/dist/{chunk-I7HKKMUJ.js → chunk-DSPP6CZL.js} +48 -3
  19. package/dist/chunk-DSPP6CZL.js.map +1 -0
  20. package/dist/index.js +4 -4
  21. package/dist/index.js.map +1 -1
  22. package/dist/observability-metrics.d.ts +11 -1
  23. package/dist/sandbox-resume.d.ts +46 -0
  24. package/dist/workflow-bundle.js +77 -2
  25. package/dist/workflows/session.d.ts +30 -0
  26. package/package.json +20 -19
  27. package/src/activities/agent-turn/agent-build.ts +4 -0
  28. package/src/activities/agent-turn/code-search.ts +275 -0
  29. package/src/activities/agent-turn/codex-capacity.ts +37 -2
  30. package/src/activities/agent-turn/compaction-prep.ts +52 -16
  31. package/src/activities/agent-turn/errors.ts +59 -1
  32. package/src/activities/agent-turn/governance-model.ts +17 -1
  33. package/src/activities/agent-turn/run.ts +4 -0
  34. package/src/activities/agent-turn/sandbox-establish.ts +12 -1
  35. package/src/activities/agent-turn/session-title.ts +73 -3
  36. package/src/activities/agent-turn/stream-attempt.ts +14 -13
  37. package/src/activities/agent-turn/tool-environment.ts +65 -0
  38. package/src/activities/context-compaction.ts +49 -14
  39. package/src/activities/knowledge-indexing.ts +107 -9
  40. package/src/activities/scheduled-tasks.ts +18 -2
  41. package/src/activity-services.ts +16 -4
  42. package/src/editable-artifact-hint-broker.ts +3 -0
  43. package/src/index.ts +2 -2
  44. package/src/observability-metrics.ts +70 -1
  45. package/src/personal-github-git-credentials.ts +2 -0
  46. package/src/sandbox-resume.ts +205 -5
  47. package/src/workflows/session.ts +102 -6
  48. package/dist/activities-control-IVTL723D.js.map +0 -1
  49. package/dist/activities-turn-EZEDZTEZ.js.map +0 -1
  50. package/dist/chunk-I7HKKMUJ.js.map +0 -1
  51. package/dist/chunk-JMO5ZUW3.js.map +0 -1
@@ -130,6 +130,9 @@ async function connectEditableArtifactHintBroker(input) {
130
130
  name,
131
131
  reconnect: true,
132
132
  maxReconnectAttempts: -1,
133
+ // Same policy as the event bus: a broker or auth-callout restart must not
134
+ // permanently close this connection after two identical auth errors.
135
+ ignoreAuthErrorAbort: true,
133
136
  reconnectTimeWait: 2e3,
134
137
  reconnectJitter: 1e3,
135
138
  reconnectJitterTLS: 1e3,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/editable-artifact-outbox-service.ts","../src/editable-artifact-outbox-dispatcher.ts","../src/editable-artifact-hint-broker.ts","../src/artifact-outbox-entry.ts"],"sourcesContent":["import {\n dbSearchPath,\n getArtifactOutboxSettings,\n resolveNatsControlPlaneAuth,\n type ArtifactOutboxSettings,\n} from \"@opengeni/config\";\nimport type { EditableArtifactOutboxDispatchSummary } from \"@opengeni/core\";\nimport { createObservability, type Observability } from \"@opengeni/observability\";\n\nimport {\n EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV,\n EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE,\n createEditableArtifactOutboxWorker,\n type EditableArtifactOutboxWorkerRuntime,\n} from \"./editable-artifact-outbox-dispatcher\";\nimport type { EditableArtifactHintNatsAuth } from \"./editable-artifact-hint-broker\";\n\nexport type EditableArtifactOutboxServiceState =\n | \"starting\"\n | \"ready\"\n | \"draining\"\n | \"stopped\"\n | \"failed\";\n\nexport interface EditableArtifactOutboxRuntimePort {\n start(): Promise<void>;\n drain(): boolean;\n stop(): Promise<void>;\n check(signal?: AbortSignal): Promise<void>;\n readonly dispatcher: Readonly<{\n dispatchOnce(): Promise<EditableArtifactOutboxDispatchSummary>;\n }>;\n}\n\nexport type EditableArtifactOutboxService = Readonly<{\n state(): EditableArtifactOutboxServiceState;\n run(): Promise<void>;\n drain(reason?: string): boolean;\n close(): Promise<void>;\n dispatchOnce(): Promise<EditableArtifactOutboxDispatchSummary>;\n fetch(request: Request): Promise<Response>;\n}>;\n\nexport type CreateEditableArtifactOutboxServiceInput = Readonly<{\n runtime: EditableArtifactOutboxRuntimePort;\n observability: Observability;\n serviceName: string;\n environment: string;\n deploymentRevision?: string;\n readinessTimeoutMs?: number;\n}>;\n\nexport type ProductionEditableArtifactOutboxServiceOptions = Readonly<{\n settings: ArtifactOutboxSettings;\n databaseUrl: string;\n declaredDatabaseRole: string;\n natsUrl: string;\n natsAuth: EditableArtifactHintNatsAuth;\n owner: string;\n databasePoolSize?: number;\n batchSize?: number;\n concurrency?: number;\n leaseDurationMs?: number;\n leaseRenewIntervalMs?: number;\n pollIntervalMs?: number;\n publishTimeoutMs?: number;\n retryBaseMs?: number;\n retryMaxMs?: number;\n}>;\n\n/** Compose the independently supervised production outbox dispatcher. */\nexport async function createProductionEditableArtifactOutboxService(\n options: ProductionEditableArtifactOutboxServiceOptions,\n): Promise<EditableArtifactOutboxService> {\n if (options.declaredDatabaseRole !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE) {\n throw new Error(\"Artifact outbox dispatcher database role declaration is invalid\");\n }\n const observability = createObservability(options.settings, {\n component: \"artifact-outbox-dispatcher\",\n });\n const databaseSearchPath = dbSearchPath(options.settings);\n const runtime = await createEditableArtifactOutboxWorker({\n dispatcherDatabaseUrl: options.databaseUrl,\n ...(databaseSearchPath ? { databaseSearchPath } : {}),\n ...(options.databasePoolSize === undefined\n ? {}\n : { databasePoolSize: options.databasePoolSize }),\n natsUrl: options.natsUrl,\n natsAuth: options.natsAuth,\n owner: options.owner,\n dispatcher: {\n ...(options.batchSize === undefined ? {} : { batchSize: options.batchSize }),\n ...(options.concurrency === undefined ? {} : { concurrency: options.concurrency }),\n ...(options.leaseDurationMs === undefined\n ? {}\n : { leaseDurationMs: options.leaseDurationMs }),\n ...(options.leaseRenewIntervalMs === undefined\n ? {}\n : { leaseRenewIntervalMs: options.leaseRenewIntervalMs }),\n ...(options.pollIntervalMs === undefined ? {} : { pollIntervalMs: options.pollIntervalMs }),\n ...(options.publishTimeoutMs === undefined\n ? {}\n : { publishTimeoutMs: options.publishTimeoutMs }),\n ...(options.retryBaseMs === undefined ? {} : { retryBaseMs: options.retryBaseMs }),\n ...(options.retryMaxMs === undefined ? {} : { retryMaxMs: options.retryMaxMs }),\n },\n metrics: {\n increment(outcome, count = 1) {\n observability.incrementCounter({\n name: \"opengeni_artifact_outbox_dispatch_total\",\n help: \"Editable artifact outbox dispatch actions by closed outcome.\",\n labels: { outcome },\n amount: count,\n });\n },\n observePublishSeconds(outcome, seconds) {\n observability.observeHistogram({\n name: \"opengeni_artifact_outbox_publish_seconds\",\n help: \"Editable artifact broker publication latency by closed outcome.\",\n labels: { outcome },\n value: seconds,\n });\n },\n },\n logger: {\n warn(message, attributes) {\n observability.warn(message, {\n errorClass: \"WorkerOperationError\",\n errorCode: \"worker_operation_failed\",\n origin: \"worker\",\n outcome: typeof attributes.code === \"string\" ? attributes.code : \"unknown\",\n });\n },\n },\n });\n return createEditableArtifactOutboxService({\n runtime,\n observability,\n serviceName: options.settings.serviceName,\n environment: options.settings.environment,\n deploymentRevision: options.settings.deploymentRevision,\n });\n}\n\nexport function createEditableArtifactOutboxService(\n input: CreateEditableArtifactOutboxServiceInput,\n): EditableArtifactOutboxService {\n let state: EditableArtifactOutboxServiceState = \"starting\";\n let runPromise: Promise<void> | null = null;\n let closePromise: Promise<void> | null = null;\n let readinessPromise: Promise<void> | null = null;\n const readinessTimeoutMs = input.readinessTimeoutMs ?? 2_000;\n\n const ready = (): Promise<void> => {\n if (readinessPromise) return readinessPromise;\n const abort = new AbortController();\n const check = withTimeout(input.runtime.check(abort.signal), readinessTimeoutMs, abort);\n readinessPromise = check;\n void check.then(\n () => {\n if (readinessPromise === check) readinessPromise = null;\n },\n () => {\n if (readinessPromise === check) readinessPromise = null;\n },\n );\n return check;\n };\n\n const run = (): Promise<void> => {\n if (runPromise) return runPromise;\n if (state !== \"starting\") {\n return Promise.reject(new Error(\"Artifact outbox dispatcher service cannot be restarted\"));\n }\n runPromise = (async () => {\n try {\n await ready();\n if ((state as EditableArtifactOutboxServiceState) === \"draining\") {\n state = \"stopped\";\n return;\n }\n const running = input.runtime.start();\n state = \"ready\";\n await running;\n const exitWasDraining = (state as EditableArtifactOutboxServiceState) === \"draining\";\n state = exitWasDraining ? \"stopped\" : \"failed\";\n if (!exitWasDraining) {\n throw new Error(\"Artifact outbox dispatcher exited without a drain request\");\n }\n } catch (error) {\n const caughtState = state as EditableArtifactOutboxServiceState;\n if (caughtState !== \"draining\" && caughtState !== \"stopped\") state = \"failed\";\n throw error;\n }\n })();\n return runPromise;\n };\n\n const drain = (_reason = \"shutdown\"): boolean => {\n if (state === \"draining\" || state === \"stopped\" || state === \"failed\") return false;\n state = \"draining\";\n input.runtime.drain();\n return true;\n };\n\n const close = (): Promise<void> => {\n if (closePromise) return closePromise;\n closePromise = (async () => {\n drain(\"close\");\n if (runPromise) await runPromise.catch(() => undefined);\n await input.runtime.stop();\n if (state !== \"failed\") state = \"stopped\";\n })();\n return closePromise;\n };\n\n const fetch = async (request: Request): Promise<Response> => {\n const url = new URL(request.url);\n if (request.method !== \"GET\") {\n return Response.json({ error: \"method_not_allowed\" }, { status: 405 });\n }\n if (url.pathname === \"/healthz\") {\n const ok = state !== \"failed\" && state !== \"stopped\";\n return Response.json(\n {\n service: input.serviceName,\n component: \"artifact-outbox-dispatcher\",\n environment: input.environment,\n ...(input.deploymentRevision ? { deploymentRevision: input.deploymentRevision } : {}),\n state,\n ok,\n },\n { status: ok ? 200 : 503 },\n );\n }\n if (url.pathname === \"/readyz\") {\n if (state !== \"ready\") {\n return Response.json(\n {\n ok: false,\n state,\n checks: { databaseRole: { ok: false }, nats: { ok: false } },\n },\n { status: 503 },\n );\n }\n try {\n await ready();\n return Response.json({\n ok: true,\n state,\n checks: { databaseRole: { ok: true }, nats: { ok: true } },\n });\n } catch {\n return Response.json(\n {\n ok: false,\n state,\n checks: { databaseRole: { ok: false }, nats: { ok: false } },\n },\n { status: 503 },\n );\n }\n }\n if (url.pathname === \"/metrics\") {\n return new Response(await input.observability.prometheusMetrics(), {\n status: 200,\n headers: { \"content-type\": \"text/plain; version=0.0.4; charset=utf-8\" },\n });\n }\n return Response.json({ error: \"not_found\" }, { status: 404 });\n };\n\n return Object.freeze({\n state: () => state,\n run,\n drain,\n close,\n dispatchOnce: async () => await input.runtime.dispatcher.dispatchOnce(),\n fetch,\n });\n}\n\nexport type EditableArtifactOutboxSidecarEnvironment = Readonly<{\n databaseUrl: string;\n declaredDatabaseRole: string;\n owner: string;\n httpPort: number;\n databasePoolSize: number;\n batchSize: number;\n concurrency: number;\n leaseDurationMs: number;\n leaseRenewIntervalMs: number;\n pollIntervalMs: number;\n publishTimeoutMs: number;\n retryBaseMs: number;\n retryMaxMs: number;\n}>;\n\nexport function readEditableArtifactOutboxSidecarEnvironment(\n environment: NodeJS.ProcessEnv = process.env,\n): EditableArtifactOutboxSidecarEnvironment | null {\n if (environment.OPENGENI_ARTIFACT_OUTBOX_ENABLED !== \"true\") return null;\n const declaredDatabaseRole = required(environment, \"OPENGENI_ARTIFACT_OUTBOX_DATABASE_ROLE\");\n if (declaredDatabaseRole !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE) {\n throw new Error(\"OPENGENI_ARTIFACT_OUTBOX_DATABASE_ROLE is invalid\");\n }\n const result = {\n databaseUrl: required(environment, EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV),\n declaredDatabaseRole,\n owner:\n environment.OPENGENI_ARTIFACT_OUTBOX_OWNER?.trim() ||\n `artifact-outbox-${process.pid}-${crypto.randomUUID()}`,\n httpPort: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_HTTP_PORT\", 9466, 1, 65_535),\n databasePoolSize: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_DB_POOL_SIZE\", 4, 1, 8),\n batchSize: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_BATCH_SIZE\", 32, 1, 1_000),\n concurrency: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_CONCURRENCY\", 8, 1, 128),\n leaseDurationMs: integer(\n environment,\n \"OPENGENI_ARTIFACT_OUTBOX_LEASE_MS\",\n 30_000,\n 1_000,\n 86_400_000,\n ),\n leaseRenewIntervalMs: integer(\n environment,\n \"OPENGENI_ARTIFACT_OUTBOX_RENEW_MS\",\n 10_000,\n 100,\n 43_199_999,\n ),\n pollIntervalMs: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_POLL_MS\", 500, 10, 60_000),\n publishTimeoutMs: integer(\n environment,\n \"OPENGENI_ARTIFACT_OUTBOX_PUBLISH_TIMEOUT_MS\",\n 5_000,\n 100,\n 60_000,\n ),\n retryBaseMs: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_RETRY_BASE_MS\", 500, 10, 60_000),\n retryMaxMs: integer(\n environment,\n \"OPENGENI_ARTIFACT_OUTBOX_RETRY_MAX_MS\",\n 60_000,\n 10,\n 86_400_000,\n ),\n } as const;\n if (result.leaseRenewIntervalMs >= result.leaseDurationMs) {\n throw new Error(\"OPENGENI_ARTIFACT_OUTBOX_RENEW_MS must be less than lease duration\");\n }\n if (result.retryBaseMs > result.retryMaxMs) {\n throw new Error(\"OPENGENI_ARTIFACT_OUTBOX_RETRY_BASE_MS must not exceed retry max\");\n }\n return Object.freeze(result);\n}\n\nexport async function createOutboxSidecarFromEnvironment(\n environment: NodeJS.ProcessEnv = process.env,\n): Promise<Readonly<{ service: EditableArtifactOutboxService; httpPort: number }> | null> {\n const sidecar = readEditableArtifactOutboxSidecarEnvironment(environment);\n if (!sidecar) return null;\n const settings = getArtifactOutboxSettings(environment);\n const controlPlaneAuth = resolveNatsControlPlaneAuth(settings);\n const natsAuth: EditableArtifactHintNatsAuth = controlPlaneAuth\n ? {\n kind: \"user-password\",\n user: controlPlaneAuth.user,\n pass: controlPlaneAuth.password,\n }\n : { kind: \"anonymous\" };\n const service = await createProductionEditableArtifactOutboxService({\n settings,\n databaseUrl: sidecar.databaseUrl,\n declaredDatabaseRole: sidecar.declaredDatabaseRole,\n natsUrl: settings.natsUrl,\n natsAuth,\n owner: sidecar.owner,\n databasePoolSize: sidecar.databasePoolSize,\n batchSize: sidecar.batchSize,\n concurrency: sidecar.concurrency,\n leaseDurationMs: sidecar.leaseDurationMs,\n leaseRenewIntervalMs: sidecar.leaseRenewIntervalMs,\n pollIntervalMs: sidecar.pollIntervalMs,\n publishTimeoutMs: sidecar.publishTimeoutMs,\n retryBaseMs: sidecar.retryBaseMs,\n retryMaxMs: sidecar.retryMaxMs,\n });\n return Object.freeze({ service, httpPort: sidecar.httpPort });\n}\n\nasync function withTimeout<T>(\n promise: Promise<T>,\n milliseconds: number,\n abort: AbortController,\n): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n promise,\n new Promise<never>((_resolve, reject) => {\n timer = setTimeout(() => {\n abort.abort();\n reject(new Error(\"readiness check timed out\"));\n }, milliseconds);\n }),\n ]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n}\n\nfunction required(environment: NodeJS.ProcessEnv, name: string): string {\n const value = environment[name]?.trim();\n if (!value) throw new Error(`${name} is required when artifact outbox dispatch is enabled`);\n return value;\n}\n\nfunction integer(\n environment: NodeJS.ProcessEnv,\n name: string,\n fallback: number,\n minimum: number,\n maximum: number,\n): number {\n const raw = environment[name];\n const value = raw === undefined ? fallback : Number(raw);\n if (!Number.isSafeInteger(value) || value < minimum || value > maximum) {\n throw new Error(`${name} is outside its allowed range`);\n }\n return value;\n}\n\n// Compile-time assurance that production composition satisfies the service port.\nconst _runtimePort: EditableArtifactOutboxRuntimePort | undefined = undefined as\n | EditableArtifactOutboxWorkerRuntime\n | undefined;\nvoid _runtimePort;\n","import {\n EditableArtifactLiveOutboxDispatcher,\n MathEditableArtifactOutboxRandom,\n SystemEditableArtifactLiveClock,\n SystemEditableArtifactLiveScheduler,\n type EditableArtifactOutboxDispatcherOptions,\n type EditableArtifactOutboxLoggerPort,\n type EditableArtifactOutboxMetricsPort,\n type EditableArtifactOutboxDispatcherStorePort,\n type EditableArtifactLiveOutboxRecord,\n} from \"@opengeni/core\";\nimport {\n PostgresEditableArtifactStore,\n createDb,\n dbSql,\n type Database,\n type DbClient,\n} from \"@opengeni/db\";\n\nimport {\n connectEditableArtifactHintBroker,\n type ConfirmedNatsEditableArtifactHintBroker,\n type EditableArtifactHintNatsAuth,\n} from \"./editable-artifact-hint-broker\";\n\nexport const EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE =\n \"opengeni_artifact_outbox_dispatcher\";\nexport const EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV = \"OPENGENI_ARTIFACT_OUTBOX_DATABASE_URL\";\n\nexport type EditableArtifactOutboxWorkerOptions = Readonly<{\n /** Must authenticate as the dedicated dispatcher role, never the generic app role. */\n dispatcherDatabaseUrl: string;\n databaseSearchPath?: string;\n databasePoolSize?: number;\n natsUrl: string;\n natsAuth: EditableArtifactHintNatsAuth;\n owner?: string;\n dispatcher?: Omit<EditableArtifactOutboxDispatcherOptions, \"owner\">;\n metrics?: EditableArtifactOutboxMetricsPort;\n logger?: EditableArtifactOutboxLoggerPort;\n}>;\n\n/** Explicit lifecycle handle; hosts supervise `start()` and await `stop()` on drain. */\nexport class EditableArtifactOutboxWorkerRuntime {\n private readonly abort = new AbortController();\n private running: Promise<void> | null = null;\n private closing: Promise<void> | null = null;\n\n constructor(\n readonly dispatcher: EditableArtifactLiveOutboxDispatcher,\n private readonly broker: ConfirmedNatsEditableArtifactHintBroker,\n private readonly database: DbClient,\n ) {}\n\n start(): Promise<void> {\n if (this.closing) return Promise.reject(new Error(\"Artifact outbox worker is stopping\"));\n this.running ??= this.dispatcher.run(this.abort.signal);\n return this.running;\n }\n\n drain(): boolean {\n if (this.abort.signal.aborted) return false;\n this.abort.abort();\n return true;\n }\n\n async check(signal?: AbortSignal): Promise<void> {\n if (this.abort.signal.aborted || this.closing) {\n throw new Error(\"Artifact outbox worker is stopping\");\n }\n await Promise.all([\n assertDedicatedOutboxDispatcherDatabaseRole(this.database.db),\n this.broker.check(signal),\n ]);\n }\n\n stop(): Promise<void> {\n if (this.closing) return this.closing;\n this.closing = this.stopOnce();\n return this.closing;\n }\n\n private async stopOnce(): Promise<void> {\n this.drain();\n const running = this.running ? await Promise.allSettled([this.running]) : [];\n const cleanup = await Promise.allSettled([this.broker.close(), this.database.close()]);\n const failure = [...running, ...cleanup].find(\n (result): result is PromiseRejectedResult => result.status === \"rejected\",\n );\n if (failure) throw failure.reason;\n }\n}\n\n/**\n * Production composition. DB grants make the role a narrow capability: it can\n * execute only lease-fenced dispatcher functions and cannot read artifact rows.\n */\nexport async function createEditableArtifactOutboxWorker(\n options: EditableArtifactOutboxWorkerOptions,\n): Promise<EditableArtifactOutboxWorkerRuntime> {\n const dispatcherDatabaseUrl = dedicatedDispatcherDatabaseUrl(options.dispatcherDatabaseUrl);\n const databasePoolSize = options.databasePoolSize ?? 2;\n if (!Number.isSafeInteger(databasePoolSize) || databasePoolSize < 1 || databasePoolSize > 8) {\n throw new TypeError(\"Artifact outbox dispatcher DB pool size must be 1-8\");\n }\n const database = createDb(dispatcherDatabaseUrl, {\n max: databasePoolSize,\n ...(options.databaseSearchPath ? { searchPath: options.databaseSearchPath } : {}),\n });\n let broker: ConfirmedNatsEditableArtifactHintBroker;\n try {\n await assertDedicatedOutboxDispatcherDatabaseRole(database.db);\n broker = await connectEditableArtifactHintBroker({\n natsUrl: options.natsUrl,\n auth: options.natsAuth,\n });\n } catch (error) {\n await database.close();\n throw error;\n }\n const persistence = new PostgresEditableArtifactStore(database.db);\n const store = dispatcherStore(persistence);\n const dispatcher = new EditableArtifactLiveOutboxDispatcher(\n {\n store,\n broker,\n clock: new SystemEditableArtifactLiveClock(),\n scheduler: new SystemEditableArtifactLiveScheduler(),\n random: new MathEditableArtifactOutboxRandom(),\n ...(options.metrics ? { metrics: options.metrics } : {}),\n ...(options.logger ? { logger: options.logger } : {}),\n },\n {\n owner: options.owner ?? `artifact-outbox:${crypto.randomUUID()}`,\n ...options.dispatcher,\n },\n );\n return new EditableArtifactOutboxWorkerRuntime(dispatcher, broker, database);\n}\n\n/**\n * Verify the database identity and its negative capability at runtime. A DSN\n * username check alone is insufficient because PostgreSQL role inheritance,\n * SET ROLE, or a mis-provisioned grant could otherwise widen this worker.\n */\nexport async function assertDedicatedOutboxDispatcherDatabaseRole(db: Database): Promise<void> {\n const raw = await db.execute<{\n current_role: string;\n session_role: string;\n can_access_any_relation: boolean;\n can_access_any_sequence: boolean;\n }>(dbSql`\n select\n current_user::text as current_role,\n session_user::text as session_role,\n exists (\n select 1\n from pg_catalog.pg_class relation_row\n join pg_catalog.pg_namespace namespace_row\n on namespace_row.oid = relation_row.relnamespace\n where namespace_row.nspname = current_schema()\n and relation_row.relkind in ('r', 'p', 'v', 'm', 'f')\n and (\n has_table_privilege(current_user, relation_row.oid, 'SELECT')\n or has_table_privilege(current_user, relation_row.oid, 'INSERT')\n or has_table_privilege(current_user, relation_row.oid, 'UPDATE')\n or has_table_privilege(current_user, relation_row.oid, 'DELETE')\n or has_table_privilege(current_user, relation_row.oid, 'TRUNCATE')\n or has_table_privilege(current_user, relation_row.oid, 'REFERENCES')\n or has_table_privilege(current_user, relation_row.oid, 'TRIGGER')\n or has_any_column_privilege(current_user, relation_row.oid, 'SELECT')\n or has_any_column_privilege(current_user, relation_row.oid, 'INSERT')\n or has_any_column_privilege(current_user, relation_row.oid, 'UPDATE')\n or has_any_column_privilege(current_user, relation_row.oid, 'REFERENCES')\n )\n ) as can_access_any_relation,\n exists (\n select 1\n from pg_catalog.pg_class sequence_row\n join pg_catalog.pg_namespace namespace_row\n on namespace_row.oid = sequence_row.relnamespace\n where namespace_row.nspname = current_schema()\n and sequence_row.relkind = 'S'\n and (\n has_sequence_privilege(current_user, sequence_row.oid, 'USAGE')\n or has_sequence_privilege(current_user, sequence_row.oid, 'SELECT')\n or has_sequence_privilege(current_user, sequence_row.oid, 'UPDATE')\n )\n ) as can_access_any_sequence\n `);\n const rows = Array.isArray(raw) ? raw : ((raw as unknown as { rows?: unknown[] }).rows ?? []);\n const row = rows[0] as\n | {\n current_role?: unknown;\n session_role?: unknown;\n can_access_any_relation?: unknown;\n can_access_any_sequence?: unknown;\n }\n | undefined;\n if (\n row?.current_role !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE ||\n row.session_role !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE ||\n row.can_access_any_relation !== false ||\n row.can_access_any_sequence !== false\n ) {\n throw new Error(\"Artifact outbox dispatcher database connection has an unsafe role posture\");\n }\n}\n\nfunction dispatcherStore(\n persistence: PostgresEditableArtifactStore,\n): EditableArtifactOutboxDispatcherStorePort {\n return {\n claimLiveOutbox: async (input) =>\n (await persistence.claimLiveOutbox(\n input,\n )) as unknown as readonly EditableArtifactLiveOutboxRecord[],\n renewLiveOutbox: async (input) => await persistence.renewLiveOutbox(input),\n markLiveOutboxPublished: async (input) => await persistence.markLiveOutboxPublished(input),\n retryLiveOutbox: async (input) => await persistence.retryLiveOutbox(input),\n deadLetterLiveOutbox: async (input) => await persistence.deadLetterLiveOutbox(input),\n };\n}\n\nexport function dedicatedDispatcherDatabaseUrl(raw: string): string {\n if (typeof raw !== \"string\" || raw.length > 8_192 || raw.trim() !== raw) {\n throw new TypeError(`${EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV} is malformed`);\n }\n let url: URL;\n try {\n url = new URL(raw);\n } catch (cause) {\n throw new TypeError(`${EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV} is malformed`, { cause });\n }\n if (\n (url.protocol !== \"postgres:\" && url.protocol !== \"postgresql:\") ||\n decodeURIComponent(url.username) !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE\n ) {\n throw new TypeError(\n `${EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV} must authenticate as ${EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE}`,\n );\n }\n return raw;\n}\n","import {\n EDITABLE_ARTIFACT_HINT_MAX_BYTES,\n type EditableArtifactHintBrokerPort,\n} from \"@opengeni/core\";\nimport { connect, type NatsConnection } from \"@opengeni/events\";\n\nconst DEFAULT_CONNECTION_NAME = \"opengeni-editable-artifact-outbox\";\n\nexport type EditableArtifactHintNatsAuth =\n | Readonly<{ kind: \"user-password\"; user: string; pass: string }>\n | Readonly<{ kind: \"token\"; token: string }>\n | Readonly<{ kind: \"anonymous\" }>;\n\nexport type EditableArtifactHintNatsBrokerOptions = Readonly<{\n maxHintBytes?: number;\n}>;\n\nexport type EditableArtifactHintNatsConnection = Pick<\n NatsConnection,\n \"publish\" | \"flush\" | \"drain\" | \"close\" | \"closed\" | \"isClosed\" | \"isDraining\"\n>;\n\n/**\n * Core-NATS adapter for the durable outbox. A publish resolves only after a\n * server round-trip flush ACK. Reconnect buffering may create duplicates after\n * a timeout; hints are intentionally idempotent wakeups for durable gap-fill.\n */\nexport class ConfirmedNatsEditableArtifactHintBroker implements EditableArtifactHintBrokerPort {\n private readonly maxHintBytes: number;\n\n constructor(\n private readonly connection: EditableArtifactHintNatsConnection,\n options: EditableArtifactHintNatsBrokerOptions = {},\n ) {\n this.maxHintBytes = options.maxHintBytes ?? EDITABLE_ARTIFACT_HINT_MAX_BYTES;\n if (\n !Number.isSafeInteger(this.maxHintBytes) ||\n this.maxHintBytes < 1 ||\n this.maxHintBytes > EDITABLE_ARTIFACT_HINT_MAX_BYTES\n ) {\n throw new TypeError(\"Editable artifact NATS hint byte limit is invalid\");\n }\n }\n\n async publish(\n input: Readonly<{\n subject: string;\n payload: Uint8Array;\n signal: AbortSignal;\n }>,\n ): Promise<void> {\n assertSubject(input.subject);\n if (\n !(input.payload instanceof Uint8Array) ||\n input.payload.byteLength < 1 ||\n input.payload.byteLength > this.maxHintBytes\n ) {\n throw new EditableArtifactNatsHintPublishError(\n \"broker_backpressure\",\n \"Editable artifact hint exceeds the NATS envelope\",\n );\n }\n if (input.signal.aborted) throw abortedPublish();\n if (this.connection.isClosed() || this.connection.isDraining()) {\n throw new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS connection is closed\",\n );\n }\n try {\n this.connection.publish(input.subject, input.payload);\n await abortable(this.connection.flush(), input.signal);\n } catch (error) {\n if (input.signal.aborted) throw abortedPublish();\n if (error instanceof EditableArtifactNatsHintPublishError) throw error;\n throw new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS publish was not acknowledged\",\n { cause: error },\n );\n }\n }\n\n /**\n * A readiness probe must prove the server is reachable, not merely that the\n * client object has not observed closure yet. `flush()` is a bounded NATS\n * round trip and has the same acknowledgement semantics as publication.\n */\n async check(signal: AbortSignal = new AbortController().signal): Promise<void> {\n if (signal.aborted) throw abortedPublish();\n if (this.connection.isClosed() || this.connection.isDraining()) {\n throw new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS connection is unavailable\",\n );\n }\n try {\n await abortable(this.connection.flush(), signal);\n } catch (error) {\n if (error instanceof EditableArtifactNatsHintPublishError) throw error;\n throw new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS readiness round trip failed\",\n { cause: error },\n );\n }\n }\n\n async close(drainTimeoutMs = 5_000): Promise<void> {\n if (!Number.isSafeInteger(drainTimeoutMs) || drainTimeoutMs < 1 || drainTimeoutMs > 30_000) {\n throw new TypeError(\"Editable artifact NATS drain timeout is invalid\");\n }\n if (this.connection.isClosed()) return;\n if (this.connection.isDraining()) {\n await this.connection.closed();\n return;\n }\n let timer: ReturnType<typeof setTimeout> | undefined;\n const drain = this.connection.drain();\n const outcome = await Promise.race([\n drain.then(\n () => \"drained\" as const,\n () => \"failed\" as const,\n ),\n new Promise<\"timed_out\">((resolve) => {\n timer = setTimeout(() => resolve(\"timed_out\"), drainTimeoutMs);\n }),\n ]);\n if (timer) clearTimeout(timer);\n if (outcome !== \"drained\" && !this.connection.isClosed()) {\n await this.connection.close();\n }\n }\n}\n\nexport class EditableArtifactNatsHintPublishError extends Error {\n constructor(\n readonly code: \"broker_unavailable\" | \"broker_backpressure\",\n message: string,\n options?: ErrorOptions,\n ) {\n super(message, options);\n this.name = \"EditableArtifactNatsHintPublishError\";\n }\n}\n\n/** Opens one resilient dispatcher identity; callers own `broker.close()`. */\nexport async function connectEditableArtifactHintBroker(\n input: Readonly<{\n natsUrl: string;\n auth: EditableArtifactHintNatsAuth;\n name?: string;\n maxHintBytes?: number;\n }>,\n): Promise<ConfirmedNatsEditableArtifactHintBroker> {\n const natsUrl = boundedText(input.natsUrl, \"NATS URL\", 2_048);\n const name = boundedText(input.name ?? DEFAULT_CONNECTION_NAME, \"NATS connection name\", 128);\n const auth = natsAuthOptions(input.auth);\n const connection = await connect({\n servers: natsUrl,\n name,\n reconnect: true,\n maxReconnectAttempts: -1,\n reconnectTimeWait: 2_000,\n reconnectJitter: 1_000,\n reconnectJitterTLS: 1_000,\n waitOnFirstConnect: true,\n pingInterval: 20_000,\n maxPingOut: 3,\n ...auth,\n });\n return new ConfirmedNatsEditableArtifactHintBroker(connection, {\n ...(input.maxHintBytes === undefined ? {} : { maxHintBytes: input.maxHintBytes }),\n });\n}\n\nfunction natsAuthOptions(auth: EditableArtifactHintNatsAuth): {\n user?: string;\n pass?: string;\n token?: string;\n} {\n if (auth.kind === \"anonymous\") return {};\n if (auth.kind === \"token\") return { token: boundedText(auth.token, \"NATS token\", 4_096) };\n return {\n user: boundedText(auth.user, \"NATS user\", 256),\n pass: boundedText(auth.pass, \"NATS password\", 4_096),\n };\n}\n\nfunction assertSubject(subject: string): void {\n const bytes = new TextEncoder().encode(subject).byteLength;\n if (\n bytes < 1 ||\n bytes > 1_024 ||\n subject.startsWith(\".\") ||\n subject.endsWith(\".\") ||\n subject.includes(\"..\") ||\n /[\\s*>]/u.test(subject)\n ) {\n throw new EditableArtifactNatsHintPublishError(\n \"broker_backpressure\",\n \"Editable artifact NATS subject is malformed\",\n );\n }\n}\n\nfunction boundedText(value: string, label: string, maxBytes: number): string {\n const bytes = new TextEncoder().encode(value).byteLength;\n if (bytes < 1 || bytes > maxBytes || value.trim() !== value) {\n throw new TypeError(`${label} is malformed`);\n }\n return value;\n}\n\nfunction abortedPublish(): EditableArtifactNatsHintPublishError {\n return new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS publish was aborted\",\n );\n}\n\nasync function abortable(operation: Promise<void>, signal: AbortSignal): Promise<void> {\n if (signal.aborted) throw abortedPublish();\n let remove: () => void = () => undefined;\n const aborted = new Promise<never>((_resolve, reject) => {\n const onAbort = () => reject(abortedPublish());\n signal.addEventListener(\"abort\", onAbort, { once: true });\n remove = () => signal.removeEventListener(\"abort\", onAbort);\n });\n try {\n await Promise.race([operation, aborted]);\n } finally {\n remove();\n }\n}\n","import { createOutboxSidecarFromEnvironment } from \"./editable-artifact-outbox-service\";\n\n/** Dedicated process: no Temporal/control worker is created or imported here. */\nexport async function runEditableArtifactOutboxSidecar(\n environment: NodeJS.ProcessEnv = process.env,\n): Promise<void> {\n const configured = await createOutboxSidecarFromEnvironment(environment);\n if (!configured) throw new Error(\"Editable artifact outbox sidecar is disabled\");\n const server = Bun.serve({\n hostname: \"0.0.0.0\",\n port: configured.httpPort,\n fetch: configured.service.fetch,\n });\n const stop = () => configured.service.drain(\"process signal\");\n process.on(\"SIGTERM\", stop);\n process.on(\"SIGINT\", stop);\n try {\n await configured.service.run();\n } finally {\n process.off(\"SIGTERM\", stop);\n process.off(\"SIGINT\", stop);\n server.stop(true);\n await configured.service.close();\n }\n}\n\nif (import.meta.main) {\n await runEditableArtifactOutboxSidecar();\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/editable-artifact-outbox-service.ts","../src/editable-artifact-outbox-dispatcher.ts","../src/editable-artifact-hint-broker.ts","../src/artifact-outbox-entry.ts"],"sourcesContent":["import {\n dbSearchPath,\n getArtifactOutboxSettings,\n resolveNatsControlPlaneAuth,\n type ArtifactOutboxSettings,\n} from \"@opengeni/config\";\nimport type { EditableArtifactOutboxDispatchSummary } from \"@opengeni/core\";\nimport { createObservability, type Observability } from \"@opengeni/observability\";\n\nimport {\n EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV,\n EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE,\n createEditableArtifactOutboxWorker,\n type EditableArtifactOutboxWorkerRuntime,\n} from \"./editable-artifact-outbox-dispatcher\";\nimport type { EditableArtifactHintNatsAuth } from \"./editable-artifact-hint-broker\";\n\nexport type EditableArtifactOutboxServiceState =\n | \"starting\"\n | \"ready\"\n | \"draining\"\n | \"stopped\"\n | \"failed\";\n\nexport interface EditableArtifactOutboxRuntimePort {\n start(): Promise<void>;\n drain(): boolean;\n stop(): Promise<void>;\n check(signal?: AbortSignal): Promise<void>;\n readonly dispatcher: Readonly<{\n dispatchOnce(): Promise<EditableArtifactOutboxDispatchSummary>;\n }>;\n}\n\nexport type EditableArtifactOutboxService = Readonly<{\n state(): EditableArtifactOutboxServiceState;\n run(): Promise<void>;\n drain(reason?: string): boolean;\n close(): Promise<void>;\n dispatchOnce(): Promise<EditableArtifactOutboxDispatchSummary>;\n fetch(request: Request): Promise<Response>;\n}>;\n\nexport type CreateEditableArtifactOutboxServiceInput = Readonly<{\n runtime: EditableArtifactOutboxRuntimePort;\n observability: Observability;\n serviceName: string;\n environment: string;\n deploymentRevision?: string;\n readinessTimeoutMs?: number;\n}>;\n\nexport type ProductionEditableArtifactOutboxServiceOptions = Readonly<{\n settings: ArtifactOutboxSettings;\n databaseUrl: string;\n declaredDatabaseRole: string;\n natsUrl: string;\n natsAuth: EditableArtifactHintNatsAuth;\n owner: string;\n databasePoolSize?: number;\n batchSize?: number;\n concurrency?: number;\n leaseDurationMs?: number;\n leaseRenewIntervalMs?: number;\n pollIntervalMs?: number;\n publishTimeoutMs?: number;\n retryBaseMs?: number;\n retryMaxMs?: number;\n}>;\n\n/** Compose the independently supervised production outbox dispatcher. */\nexport async function createProductionEditableArtifactOutboxService(\n options: ProductionEditableArtifactOutboxServiceOptions,\n): Promise<EditableArtifactOutboxService> {\n if (options.declaredDatabaseRole !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE) {\n throw new Error(\"Artifact outbox dispatcher database role declaration is invalid\");\n }\n const observability = createObservability(options.settings, {\n component: \"artifact-outbox-dispatcher\",\n });\n const databaseSearchPath = dbSearchPath(options.settings);\n const runtime = await createEditableArtifactOutboxWorker({\n dispatcherDatabaseUrl: options.databaseUrl,\n ...(databaseSearchPath ? { databaseSearchPath } : {}),\n ...(options.databasePoolSize === undefined\n ? {}\n : { databasePoolSize: options.databasePoolSize }),\n natsUrl: options.natsUrl,\n natsAuth: options.natsAuth,\n owner: options.owner,\n dispatcher: {\n ...(options.batchSize === undefined ? {} : { batchSize: options.batchSize }),\n ...(options.concurrency === undefined ? {} : { concurrency: options.concurrency }),\n ...(options.leaseDurationMs === undefined\n ? {}\n : { leaseDurationMs: options.leaseDurationMs }),\n ...(options.leaseRenewIntervalMs === undefined\n ? {}\n : { leaseRenewIntervalMs: options.leaseRenewIntervalMs }),\n ...(options.pollIntervalMs === undefined ? {} : { pollIntervalMs: options.pollIntervalMs }),\n ...(options.publishTimeoutMs === undefined\n ? {}\n : { publishTimeoutMs: options.publishTimeoutMs }),\n ...(options.retryBaseMs === undefined ? {} : { retryBaseMs: options.retryBaseMs }),\n ...(options.retryMaxMs === undefined ? {} : { retryMaxMs: options.retryMaxMs }),\n },\n metrics: {\n increment(outcome, count = 1) {\n observability.incrementCounter({\n name: \"opengeni_artifact_outbox_dispatch_total\",\n help: \"Editable artifact outbox dispatch actions by closed outcome.\",\n labels: { outcome },\n amount: count,\n });\n },\n observePublishSeconds(outcome, seconds) {\n observability.observeHistogram({\n name: \"opengeni_artifact_outbox_publish_seconds\",\n help: \"Editable artifact broker publication latency by closed outcome.\",\n labels: { outcome },\n value: seconds,\n });\n },\n },\n logger: {\n warn(message, attributes) {\n observability.warn(message, {\n errorClass: \"WorkerOperationError\",\n errorCode: \"worker_operation_failed\",\n origin: \"worker\",\n outcome: typeof attributes.code === \"string\" ? attributes.code : \"unknown\",\n });\n },\n },\n });\n return createEditableArtifactOutboxService({\n runtime,\n observability,\n serviceName: options.settings.serviceName,\n environment: options.settings.environment,\n deploymentRevision: options.settings.deploymentRevision,\n });\n}\n\nexport function createEditableArtifactOutboxService(\n input: CreateEditableArtifactOutboxServiceInput,\n): EditableArtifactOutboxService {\n let state: EditableArtifactOutboxServiceState = \"starting\";\n let runPromise: Promise<void> | null = null;\n let closePromise: Promise<void> | null = null;\n let readinessPromise: Promise<void> | null = null;\n const readinessTimeoutMs = input.readinessTimeoutMs ?? 2_000;\n\n const ready = (): Promise<void> => {\n if (readinessPromise) return readinessPromise;\n const abort = new AbortController();\n const check = withTimeout(input.runtime.check(abort.signal), readinessTimeoutMs, abort);\n readinessPromise = check;\n void check.then(\n () => {\n if (readinessPromise === check) readinessPromise = null;\n },\n () => {\n if (readinessPromise === check) readinessPromise = null;\n },\n );\n return check;\n };\n\n const run = (): Promise<void> => {\n if (runPromise) return runPromise;\n if (state !== \"starting\") {\n return Promise.reject(new Error(\"Artifact outbox dispatcher service cannot be restarted\"));\n }\n runPromise = (async () => {\n try {\n await ready();\n if ((state as EditableArtifactOutboxServiceState) === \"draining\") {\n state = \"stopped\";\n return;\n }\n const running = input.runtime.start();\n state = \"ready\";\n await running;\n const exitWasDraining = (state as EditableArtifactOutboxServiceState) === \"draining\";\n state = exitWasDraining ? \"stopped\" : \"failed\";\n if (!exitWasDraining) {\n throw new Error(\"Artifact outbox dispatcher exited without a drain request\");\n }\n } catch (error) {\n const caughtState = state as EditableArtifactOutboxServiceState;\n if (caughtState !== \"draining\" && caughtState !== \"stopped\") state = \"failed\";\n throw error;\n }\n })();\n return runPromise;\n };\n\n const drain = (_reason = \"shutdown\"): boolean => {\n if (state === \"draining\" || state === \"stopped\" || state === \"failed\") return false;\n state = \"draining\";\n input.runtime.drain();\n return true;\n };\n\n const close = (): Promise<void> => {\n if (closePromise) return closePromise;\n closePromise = (async () => {\n drain(\"close\");\n if (runPromise) await runPromise.catch(() => undefined);\n await input.runtime.stop();\n if (state !== \"failed\") state = \"stopped\";\n })();\n return closePromise;\n };\n\n const fetch = async (request: Request): Promise<Response> => {\n const url = new URL(request.url);\n if (request.method !== \"GET\") {\n return Response.json({ error: \"method_not_allowed\" }, { status: 405 });\n }\n if (url.pathname === \"/healthz\") {\n const ok = state !== \"failed\" && state !== \"stopped\";\n return Response.json(\n {\n service: input.serviceName,\n component: \"artifact-outbox-dispatcher\",\n environment: input.environment,\n ...(input.deploymentRevision ? { deploymentRevision: input.deploymentRevision } : {}),\n state,\n ok,\n },\n { status: ok ? 200 : 503 },\n );\n }\n if (url.pathname === \"/readyz\") {\n if (state !== \"ready\") {\n return Response.json(\n {\n ok: false,\n state,\n checks: { databaseRole: { ok: false }, nats: { ok: false } },\n },\n { status: 503 },\n );\n }\n try {\n await ready();\n return Response.json({\n ok: true,\n state,\n checks: { databaseRole: { ok: true }, nats: { ok: true } },\n });\n } catch {\n return Response.json(\n {\n ok: false,\n state,\n checks: { databaseRole: { ok: false }, nats: { ok: false } },\n },\n { status: 503 },\n );\n }\n }\n if (url.pathname === \"/metrics\") {\n return new Response(await input.observability.prometheusMetrics(), {\n status: 200,\n headers: { \"content-type\": \"text/plain; version=0.0.4; charset=utf-8\" },\n });\n }\n return Response.json({ error: \"not_found\" }, { status: 404 });\n };\n\n return Object.freeze({\n state: () => state,\n run,\n drain,\n close,\n dispatchOnce: async () => await input.runtime.dispatcher.dispatchOnce(),\n fetch,\n });\n}\n\nexport type EditableArtifactOutboxSidecarEnvironment = Readonly<{\n databaseUrl: string;\n declaredDatabaseRole: string;\n owner: string;\n httpPort: number;\n databasePoolSize: number;\n batchSize: number;\n concurrency: number;\n leaseDurationMs: number;\n leaseRenewIntervalMs: number;\n pollIntervalMs: number;\n publishTimeoutMs: number;\n retryBaseMs: number;\n retryMaxMs: number;\n}>;\n\nexport function readEditableArtifactOutboxSidecarEnvironment(\n environment: NodeJS.ProcessEnv = process.env,\n): EditableArtifactOutboxSidecarEnvironment | null {\n if (environment.OPENGENI_ARTIFACT_OUTBOX_ENABLED !== \"true\") return null;\n const declaredDatabaseRole = required(environment, \"OPENGENI_ARTIFACT_OUTBOX_DATABASE_ROLE\");\n if (declaredDatabaseRole !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE) {\n throw new Error(\"OPENGENI_ARTIFACT_OUTBOX_DATABASE_ROLE is invalid\");\n }\n const result = {\n databaseUrl: required(environment, EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV),\n declaredDatabaseRole,\n owner:\n environment.OPENGENI_ARTIFACT_OUTBOX_OWNER?.trim() ||\n `artifact-outbox-${process.pid}-${crypto.randomUUID()}`,\n httpPort: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_HTTP_PORT\", 9466, 1, 65_535),\n databasePoolSize: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_DB_POOL_SIZE\", 4, 1, 8),\n batchSize: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_BATCH_SIZE\", 32, 1, 1_000),\n concurrency: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_CONCURRENCY\", 8, 1, 128),\n leaseDurationMs: integer(\n environment,\n \"OPENGENI_ARTIFACT_OUTBOX_LEASE_MS\",\n 30_000,\n 1_000,\n 86_400_000,\n ),\n leaseRenewIntervalMs: integer(\n environment,\n \"OPENGENI_ARTIFACT_OUTBOX_RENEW_MS\",\n 10_000,\n 100,\n 43_199_999,\n ),\n pollIntervalMs: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_POLL_MS\", 500, 10, 60_000),\n publishTimeoutMs: integer(\n environment,\n \"OPENGENI_ARTIFACT_OUTBOX_PUBLISH_TIMEOUT_MS\",\n 5_000,\n 100,\n 60_000,\n ),\n retryBaseMs: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_RETRY_BASE_MS\", 500, 10, 60_000),\n retryMaxMs: integer(\n environment,\n \"OPENGENI_ARTIFACT_OUTBOX_RETRY_MAX_MS\",\n 60_000,\n 10,\n 86_400_000,\n ),\n } as const;\n if (result.leaseRenewIntervalMs >= result.leaseDurationMs) {\n throw new Error(\"OPENGENI_ARTIFACT_OUTBOX_RENEW_MS must be less than lease duration\");\n }\n if (result.retryBaseMs > result.retryMaxMs) {\n throw new Error(\"OPENGENI_ARTIFACT_OUTBOX_RETRY_BASE_MS must not exceed retry max\");\n }\n return Object.freeze(result);\n}\n\nexport async function createOutboxSidecarFromEnvironment(\n environment: NodeJS.ProcessEnv = process.env,\n): Promise<Readonly<{ service: EditableArtifactOutboxService; httpPort: number }> | null> {\n const sidecar = readEditableArtifactOutboxSidecarEnvironment(environment);\n if (!sidecar) return null;\n const settings = getArtifactOutboxSettings(environment);\n const controlPlaneAuth = resolveNatsControlPlaneAuth(settings);\n const natsAuth: EditableArtifactHintNatsAuth = controlPlaneAuth\n ? {\n kind: \"user-password\",\n user: controlPlaneAuth.user,\n pass: controlPlaneAuth.password,\n }\n : { kind: \"anonymous\" };\n const service = await createProductionEditableArtifactOutboxService({\n settings,\n databaseUrl: sidecar.databaseUrl,\n declaredDatabaseRole: sidecar.declaredDatabaseRole,\n natsUrl: settings.natsUrl,\n natsAuth,\n owner: sidecar.owner,\n databasePoolSize: sidecar.databasePoolSize,\n batchSize: sidecar.batchSize,\n concurrency: sidecar.concurrency,\n leaseDurationMs: sidecar.leaseDurationMs,\n leaseRenewIntervalMs: sidecar.leaseRenewIntervalMs,\n pollIntervalMs: sidecar.pollIntervalMs,\n publishTimeoutMs: sidecar.publishTimeoutMs,\n retryBaseMs: sidecar.retryBaseMs,\n retryMaxMs: sidecar.retryMaxMs,\n });\n return Object.freeze({ service, httpPort: sidecar.httpPort });\n}\n\nasync function withTimeout<T>(\n promise: Promise<T>,\n milliseconds: number,\n abort: AbortController,\n): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n promise,\n new Promise<never>((_resolve, reject) => {\n timer = setTimeout(() => {\n abort.abort();\n reject(new Error(\"readiness check timed out\"));\n }, milliseconds);\n }),\n ]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n}\n\nfunction required(environment: NodeJS.ProcessEnv, name: string): string {\n const value = environment[name]?.trim();\n if (!value) throw new Error(`${name} is required when artifact outbox dispatch is enabled`);\n return value;\n}\n\nfunction integer(\n environment: NodeJS.ProcessEnv,\n name: string,\n fallback: number,\n minimum: number,\n maximum: number,\n): number {\n const raw = environment[name];\n const value = raw === undefined ? fallback : Number(raw);\n if (!Number.isSafeInteger(value) || value < minimum || value > maximum) {\n throw new Error(`${name} is outside its allowed range`);\n }\n return value;\n}\n\n// Compile-time assurance that production composition satisfies the service port.\nconst _runtimePort: EditableArtifactOutboxRuntimePort | undefined = undefined as\n | EditableArtifactOutboxWorkerRuntime\n | undefined;\nvoid _runtimePort;\n","import {\n EditableArtifactLiveOutboxDispatcher,\n MathEditableArtifactOutboxRandom,\n SystemEditableArtifactLiveClock,\n SystemEditableArtifactLiveScheduler,\n type EditableArtifactOutboxDispatcherOptions,\n type EditableArtifactOutboxLoggerPort,\n type EditableArtifactOutboxMetricsPort,\n type EditableArtifactOutboxDispatcherStorePort,\n type EditableArtifactLiveOutboxRecord,\n} from \"@opengeni/core\";\nimport {\n PostgresEditableArtifactStore,\n createDb,\n dbSql,\n type Database,\n type DbClient,\n} from \"@opengeni/db\";\n\nimport {\n connectEditableArtifactHintBroker,\n type ConfirmedNatsEditableArtifactHintBroker,\n type EditableArtifactHintNatsAuth,\n} from \"./editable-artifact-hint-broker\";\n\nexport const EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE =\n \"opengeni_artifact_outbox_dispatcher\";\nexport const EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV = \"OPENGENI_ARTIFACT_OUTBOX_DATABASE_URL\";\n\nexport type EditableArtifactOutboxWorkerOptions = Readonly<{\n /** Must authenticate as the dedicated dispatcher role, never the generic app role. */\n dispatcherDatabaseUrl: string;\n databaseSearchPath?: string;\n databasePoolSize?: number;\n natsUrl: string;\n natsAuth: EditableArtifactHintNatsAuth;\n owner?: string;\n dispatcher?: Omit<EditableArtifactOutboxDispatcherOptions, \"owner\">;\n metrics?: EditableArtifactOutboxMetricsPort;\n logger?: EditableArtifactOutboxLoggerPort;\n}>;\n\n/** Explicit lifecycle handle; hosts supervise `start()` and await `stop()` on drain. */\nexport class EditableArtifactOutboxWorkerRuntime {\n private readonly abort = new AbortController();\n private running: Promise<void> | null = null;\n private closing: Promise<void> | null = null;\n\n constructor(\n readonly dispatcher: EditableArtifactLiveOutboxDispatcher,\n private readonly broker: ConfirmedNatsEditableArtifactHintBroker,\n private readonly database: DbClient,\n ) {}\n\n start(): Promise<void> {\n if (this.closing) return Promise.reject(new Error(\"Artifact outbox worker is stopping\"));\n this.running ??= this.dispatcher.run(this.abort.signal);\n return this.running;\n }\n\n drain(): boolean {\n if (this.abort.signal.aborted) return false;\n this.abort.abort();\n return true;\n }\n\n async check(signal?: AbortSignal): Promise<void> {\n if (this.abort.signal.aborted || this.closing) {\n throw new Error(\"Artifact outbox worker is stopping\");\n }\n await Promise.all([\n assertDedicatedOutboxDispatcherDatabaseRole(this.database.db),\n this.broker.check(signal),\n ]);\n }\n\n stop(): Promise<void> {\n if (this.closing) return this.closing;\n this.closing = this.stopOnce();\n return this.closing;\n }\n\n private async stopOnce(): Promise<void> {\n this.drain();\n const running = this.running ? await Promise.allSettled([this.running]) : [];\n const cleanup = await Promise.allSettled([this.broker.close(), this.database.close()]);\n const failure = [...running, ...cleanup].find(\n (result): result is PromiseRejectedResult => result.status === \"rejected\",\n );\n if (failure) throw failure.reason;\n }\n}\n\n/**\n * Production composition. DB grants make the role a narrow capability: it can\n * execute only lease-fenced dispatcher functions and cannot read artifact rows.\n */\nexport async function createEditableArtifactOutboxWorker(\n options: EditableArtifactOutboxWorkerOptions,\n): Promise<EditableArtifactOutboxWorkerRuntime> {\n const dispatcherDatabaseUrl = dedicatedDispatcherDatabaseUrl(options.dispatcherDatabaseUrl);\n const databasePoolSize = options.databasePoolSize ?? 2;\n if (!Number.isSafeInteger(databasePoolSize) || databasePoolSize < 1 || databasePoolSize > 8) {\n throw new TypeError(\"Artifact outbox dispatcher DB pool size must be 1-8\");\n }\n const database = createDb(dispatcherDatabaseUrl, {\n max: databasePoolSize,\n ...(options.databaseSearchPath ? { searchPath: options.databaseSearchPath } : {}),\n });\n let broker: ConfirmedNatsEditableArtifactHintBroker;\n try {\n await assertDedicatedOutboxDispatcherDatabaseRole(database.db);\n broker = await connectEditableArtifactHintBroker({\n natsUrl: options.natsUrl,\n auth: options.natsAuth,\n });\n } catch (error) {\n await database.close();\n throw error;\n }\n const persistence = new PostgresEditableArtifactStore(database.db);\n const store = dispatcherStore(persistence);\n const dispatcher = new EditableArtifactLiveOutboxDispatcher(\n {\n store,\n broker,\n clock: new SystemEditableArtifactLiveClock(),\n scheduler: new SystemEditableArtifactLiveScheduler(),\n random: new MathEditableArtifactOutboxRandom(),\n ...(options.metrics ? { metrics: options.metrics } : {}),\n ...(options.logger ? { logger: options.logger } : {}),\n },\n {\n owner: options.owner ?? `artifact-outbox:${crypto.randomUUID()}`,\n ...options.dispatcher,\n },\n );\n return new EditableArtifactOutboxWorkerRuntime(dispatcher, broker, database);\n}\n\n/**\n * Verify the database identity and its negative capability at runtime. A DSN\n * username check alone is insufficient because PostgreSQL role inheritance,\n * SET ROLE, or a mis-provisioned grant could otherwise widen this worker.\n */\nexport async function assertDedicatedOutboxDispatcherDatabaseRole(db: Database): Promise<void> {\n const raw = await db.execute<{\n current_role: string;\n session_role: string;\n can_access_any_relation: boolean;\n can_access_any_sequence: boolean;\n }>(dbSql`\n select\n current_user::text as current_role,\n session_user::text as session_role,\n exists (\n select 1\n from pg_catalog.pg_class relation_row\n join pg_catalog.pg_namespace namespace_row\n on namespace_row.oid = relation_row.relnamespace\n where namespace_row.nspname = current_schema()\n and relation_row.relkind in ('r', 'p', 'v', 'm', 'f')\n and (\n has_table_privilege(current_user, relation_row.oid, 'SELECT')\n or has_table_privilege(current_user, relation_row.oid, 'INSERT')\n or has_table_privilege(current_user, relation_row.oid, 'UPDATE')\n or has_table_privilege(current_user, relation_row.oid, 'DELETE')\n or has_table_privilege(current_user, relation_row.oid, 'TRUNCATE')\n or has_table_privilege(current_user, relation_row.oid, 'REFERENCES')\n or has_table_privilege(current_user, relation_row.oid, 'TRIGGER')\n or has_any_column_privilege(current_user, relation_row.oid, 'SELECT')\n or has_any_column_privilege(current_user, relation_row.oid, 'INSERT')\n or has_any_column_privilege(current_user, relation_row.oid, 'UPDATE')\n or has_any_column_privilege(current_user, relation_row.oid, 'REFERENCES')\n )\n ) as can_access_any_relation,\n exists (\n select 1\n from pg_catalog.pg_class sequence_row\n join pg_catalog.pg_namespace namespace_row\n on namespace_row.oid = sequence_row.relnamespace\n where namespace_row.nspname = current_schema()\n and sequence_row.relkind = 'S'\n and (\n has_sequence_privilege(current_user, sequence_row.oid, 'USAGE')\n or has_sequence_privilege(current_user, sequence_row.oid, 'SELECT')\n or has_sequence_privilege(current_user, sequence_row.oid, 'UPDATE')\n )\n ) as can_access_any_sequence\n `);\n const rows = Array.isArray(raw) ? raw : ((raw as unknown as { rows?: unknown[] }).rows ?? []);\n const row = rows[0] as\n | {\n current_role?: unknown;\n session_role?: unknown;\n can_access_any_relation?: unknown;\n can_access_any_sequence?: unknown;\n }\n | undefined;\n if (\n row?.current_role !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE ||\n row.session_role !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE ||\n row.can_access_any_relation !== false ||\n row.can_access_any_sequence !== false\n ) {\n throw new Error(\"Artifact outbox dispatcher database connection has an unsafe role posture\");\n }\n}\n\nfunction dispatcherStore(\n persistence: PostgresEditableArtifactStore,\n): EditableArtifactOutboxDispatcherStorePort {\n return {\n claimLiveOutbox: async (input) =>\n (await persistence.claimLiveOutbox(\n input,\n )) as unknown as readonly EditableArtifactLiveOutboxRecord[],\n renewLiveOutbox: async (input) => await persistence.renewLiveOutbox(input),\n markLiveOutboxPublished: async (input) => await persistence.markLiveOutboxPublished(input),\n retryLiveOutbox: async (input) => await persistence.retryLiveOutbox(input),\n deadLetterLiveOutbox: async (input) => await persistence.deadLetterLiveOutbox(input),\n };\n}\n\nexport function dedicatedDispatcherDatabaseUrl(raw: string): string {\n if (typeof raw !== \"string\" || raw.length > 8_192 || raw.trim() !== raw) {\n throw new TypeError(`${EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV} is malformed`);\n }\n let url: URL;\n try {\n url = new URL(raw);\n } catch (cause) {\n throw new TypeError(`${EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV} is malformed`, { cause });\n }\n if (\n (url.protocol !== \"postgres:\" && url.protocol !== \"postgresql:\") ||\n decodeURIComponent(url.username) !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE\n ) {\n throw new TypeError(\n `${EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV} must authenticate as ${EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE}`,\n );\n }\n return raw;\n}\n","import {\n EDITABLE_ARTIFACT_HINT_MAX_BYTES,\n type EditableArtifactHintBrokerPort,\n} from \"@opengeni/core\";\nimport { connect, type NatsConnection } from \"@opengeni/events\";\n\nconst DEFAULT_CONNECTION_NAME = \"opengeni-editable-artifact-outbox\";\n\nexport type EditableArtifactHintNatsAuth =\n | Readonly<{ kind: \"user-password\"; user: string; pass: string }>\n | Readonly<{ kind: \"token\"; token: string }>\n | Readonly<{ kind: \"anonymous\" }>;\n\nexport type EditableArtifactHintNatsBrokerOptions = Readonly<{\n maxHintBytes?: number;\n}>;\n\nexport type EditableArtifactHintNatsConnection = Pick<\n NatsConnection,\n \"publish\" | \"flush\" | \"drain\" | \"close\" | \"closed\" | \"isClosed\" | \"isDraining\"\n>;\n\n/**\n * Core-NATS adapter for the durable outbox. A publish resolves only after a\n * server round-trip flush ACK. Reconnect buffering may create duplicates after\n * a timeout; hints are intentionally idempotent wakeups for durable gap-fill.\n */\nexport class ConfirmedNatsEditableArtifactHintBroker implements EditableArtifactHintBrokerPort {\n private readonly maxHintBytes: number;\n\n constructor(\n private readonly connection: EditableArtifactHintNatsConnection,\n options: EditableArtifactHintNatsBrokerOptions = {},\n ) {\n this.maxHintBytes = options.maxHintBytes ?? EDITABLE_ARTIFACT_HINT_MAX_BYTES;\n if (\n !Number.isSafeInteger(this.maxHintBytes) ||\n this.maxHintBytes < 1 ||\n this.maxHintBytes > EDITABLE_ARTIFACT_HINT_MAX_BYTES\n ) {\n throw new TypeError(\"Editable artifact NATS hint byte limit is invalid\");\n }\n }\n\n async publish(\n input: Readonly<{\n subject: string;\n payload: Uint8Array;\n signal: AbortSignal;\n }>,\n ): Promise<void> {\n assertSubject(input.subject);\n if (\n !(input.payload instanceof Uint8Array) ||\n input.payload.byteLength < 1 ||\n input.payload.byteLength > this.maxHintBytes\n ) {\n throw new EditableArtifactNatsHintPublishError(\n \"broker_backpressure\",\n \"Editable artifact hint exceeds the NATS envelope\",\n );\n }\n if (input.signal.aborted) throw abortedPublish();\n if (this.connection.isClosed() || this.connection.isDraining()) {\n throw new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS connection is closed\",\n );\n }\n try {\n this.connection.publish(input.subject, input.payload);\n await abortable(this.connection.flush(), input.signal);\n } catch (error) {\n if (input.signal.aborted) throw abortedPublish();\n if (error instanceof EditableArtifactNatsHintPublishError) throw error;\n throw new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS publish was not acknowledged\",\n { cause: error },\n );\n }\n }\n\n /**\n * A readiness probe must prove the server is reachable, not merely that the\n * client object has not observed closure yet. `flush()` is a bounded NATS\n * round trip and has the same acknowledgement semantics as publication.\n */\n async check(signal: AbortSignal = new AbortController().signal): Promise<void> {\n if (signal.aborted) throw abortedPublish();\n if (this.connection.isClosed() || this.connection.isDraining()) {\n throw new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS connection is unavailable\",\n );\n }\n try {\n await abortable(this.connection.flush(), signal);\n } catch (error) {\n if (error instanceof EditableArtifactNatsHintPublishError) throw error;\n throw new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS readiness round trip failed\",\n { cause: error },\n );\n }\n }\n\n async close(drainTimeoutMs = 5_000): Promise<void> {\n if (!Number.isSafeInteger(drainTimeoutMs) || drainTimeoutMs < 1 || drainTimeoutMs > 30_000) {\n throw new TypeError(\"Editable artifact NATS drain timeout is invalid\");\n }\n if (this.connection.isClosed()) return;\n if (this.connection.isDraining()) {\n await this.connection.closed();\n return;\n }\n let timer: ReturnType<typeof setTimeout> | undefined;\n const drain = this.connection.drain();\n const outcome = await Promise.race([\n drain.then(\n () => \"drained\" as const,\n () => \"failed\" as const,\n ),\n new Promise<\"timed_out\">((resolve) => {\n timer = setTimeout(() => resolve(\"timed_out\"), drainTimeoutMs);\n }),\n ]);\n if (timer) clearTimeout(timer);\n if (outcome !== \"drained\" && !this.connection.isClosed()) {\n await this.connection.close();\n }\n }\n}\n\nexport class EditableArtifactNatsHintPublishError extends Error {\n constructor(\n readonly code: \"broker_unavailable\" | \"broker_backpressure\",\n message: string,\n options?: ErrorOptions,\n ) {\n super(message, options);\n this.name = \"EditableArtifactNatsHintPublishError\";\n }\n}\n\n/** Opens one resilient dispatcher identity; callers own `broker.close()`. */\nexport async function connectEditableArtifactHintBroker(\n input: Readonly<{\n natsUrl: string;\n auth: EditableArtifactHintNatsAuth;\n name?: string;\n maxHintBytes?: number;\n }>,\n): Promise<ConfirmedNatsEditableArtifactHintBroker> {\n const natsUrl = boundedText(input.natsUrl, \"NATS URL\", 2_048);\n const name = boundedText(input.name ?? DEFAULT_CONNECTION_NAME, \"NATS connection name\", 128);\n const auth = natsAuthOptions(input.auth);\n const connection = await connect({\n servers: natsUrl,\n name,\n reconnect: true,\n maxReconnectAttempts: -1,\n // Same policy as the event bus: a broker or auth-callout restart must not\n // permanently close this connection after two identical auth errors.\n ignoreAuthErrorAbort: true,\n reconnectTimeWait: 2_000,\n reconnectJitter: 1_000,\n reconnectJitterTLS: 1_000,\n waitOnFirstConnect: true,\n pingInterval: 20_000,\n maxPingOut: 3,\n ...auth,\n });\n return new ConfirmedNatsEditableArtifactHintBroker(connection, {\n ...(input.maxHintBytes === undefined ? {} : { maxHintBytes: input.maxHintBytes }),\n });\n}\n\nfunction natsAuthOptions(auth: EditableArtifactHintNatsAuth): {\n user?: string;\n pass?: string;\n token?: string;\n} {\n if (auth.kind === \"anonymous\") return {};\n if (auth.kind === \"token\") return { token: boundedText(auth.token, \"NATS token\", 4_096) };\n return {\n user: boundedText(auth.user, \"NATS user\", 256),\n pass: boundedText(auth.pass, \"NATS password\", 4_096),\n };\n}\n\nfunction assertSubject(subject: string): void {\n const bytes = new TextEncoder().encode(subject).byteLength;\n if (\n bytes < 1 ||\n bytes > 1_024 ||\n subject.startsWith(\".\") ||\n subject.endsWith(\".\") ||\n subject.includes(\"..\") ||\n /[\\s*>]/u.test(subject)\n ) {\n throw new EditableArtifactNatsHintPublishError(\n \"broker_backpressure\",\n \"Editable artifact NATS subject is malformed\",\n );\n }\n}\n\nfunction boundedText(value: string, label: string, maxBytes: number): string {\n const bytes = new TextEncoder().encode(value).byteLength;\n if (bytes < 1 || bytes > maxBytes || value.trim() !== value) {\n throw new TypeError(`${label} is malformed`);\n }\n return value;\n}\n\nfunction abortedPublish(): EditableArtifactNatsHintPublishError {\n return new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS publish was aborted\",\n );\n}\n\nasync function abortable(operation: Promise<void>, signal: AbortSignal): Promise<void> {\n if (signal.aborted) throw abortedPublish();\n let remove: () => void = () => undefined;\n const aborted = new Promise<never>((_resolve, reject) => {\n const onAbort = () => reject(abortedPublish());\n signal.addEventListener(\"abort\", onAbort, { once: true });\n remove = () => signal.removeEventListener(\"abort\", onAbort);\n });\n try {\n await Promise.race([operation, aborted]);\n } finally {\n remove();\n }\n}\n","import { createOutboxSidecarFromEnvironment } from \"./editable-artifact-outbox-service\";\n\n/** Dedicated process: no Temporal/control worker is created or imported here. */\nexport async function runEditableArtifactOutboxSidecar(\n environment: NodeJS.ProcessEnv = process.env,\n): Promise<void> {\n const configured = await createOutboxSidecarFromEnvironment(environment);\n if (!configured) throw new Error(\"Editable artifact outbox sidecar is disabled\");\n const server = Bun.serve({\n hostname: \"0.0.0.0\",\n port: configured.httpPort,\n fetch: configured.service.fetch,\n });\n const stop = () => configured.service.drain(\"process signal\");\n process.on(\"SIGTERM\", stop);\n process.on(\"SIGINT\", stop);\n try {\n await configured.service.run();\n } finally {\n process.off(\"SIGTERM\", stop);\n process.off(\"SIGINT\", stop);\n server.stop(true);\n await configured.service.close();\n }\n}\n\nif (import.meta.main) {\n await runEditableArtifactOutboxSidecar();\n}\n"],"mappings":"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","names":[]}
@@ -1,10 +1,19 @@
1
1
  import {
2
- observabilityEventLogger
3
- } from "./chunk-I7HKKMUJ.js";
2
+ observabilityEventBusOptions
3
+ } from "./chunk-DSPP6CZL.js";
4
4
 
5
5
  // src/activity-services.ts
6
- import { dbSearchPath, getSettings, resolveNatsControlPlaneAuth } from "@opengeni/config";
7
- import { configureChildLifecycleNotices, createDb } from "@opengeni/db";
6
+ import {
7
+ codeSearchDeploymentPolicy,
8
+ dbSearchPath,
9
+ getSettings,
10
+ resolveNatsControlPlaneAuth
11
+ } from "@opengeni/config";
12
+ import {
13
+ configureChildLifecycleNotices,
14
+ configureCodeSearchDeploymentPolicy,
15
+ createDb
16
+ } from "@opengeni/db";
8
17
  import { createNatsEventBus } from "@opengeni/events";
9
18
  import { createObservability } from "@opengeni/observability";
10
19
  import { resolveCatalogSettings } from "@opengeni/core";
@@ -403,6 +412,7 @@ function createSharedActivityServices(dependencies) {
403
412
  const db = dependencies.db ?? dbClient.db;
404
413
  const resolvedSettings = (await resolveCatalogSettings(db, settings)).settings;
405
414
  configureChildLifecycleNotices({ enabled: settings.childLifecycleNoticesEnabled });
415
+ configureCodeSearchDeploymentPolicy(codeSearchDeploymentPolicy(settings));
406
416
  return {
407
417
  settings: resolvedSettings,
408
418
  catalogSourceSettings: settings,
@@ -410,7 +420,7 @@ function createSharedActivityServices(dependencies) {
410
420
  bus: dependencies.bus ?? await createNatsEventBus(
411
421
  settings.natsUrl,
412
422
  controlPlaneAuth ? { user: controlPlaneAuth.user, pass: controlPlaneAuth.password } : void 0,
413
- { logger: observabilityEventLogger(observability) }
423
+ observabilityEventBusOptions(observability)
414
424
  ),
415
425
  objectStorage: dependencies.objectStorage ?? createObjectStorage(settings),
416
426
  observability,
@@ -5191,6 +5201,42 @@ var SandboxSiblingWarmingTimeoutError = class extends SandboxWarmingTimeoutError
5191
5201
  this.name = "SandboxSiblingWarmingTimeoutError";
5192
5202
  }
5193
5203
  };
5204
+ var disposedUnreadyFreshSandboxErrors = /* @__PURE__ */ new WeakSet();
5205
+ function isReplaceableFreshSandboxReadinessTimeout(error) {
5206
+ return error instanceof SandboxExecReadinessTimeoutError && disposedUnreadyFreshSandboxErrors.has(error);
5207
+ }
5208
+ var FRESH_SANDBOX_READINESS_REPLACEMENT_BASE_DELAY_MS = 2e3;
5209
+ var FRESH_SANDBOX_READINESS_REPLACEMENT_JITTER_MS = 8e3;
5210
+ function freshSandboxReadinessReplacementDelayMs(random = Math.random) {
5211
+ const sample = random();
5212
+ const unit = Number.isFinite(sample) ? Math.min(Math.max(sample, 0), 1 - Number.EPSILON) : 0;
5213
+ return FRESH_SANDBOX_READINESS_REPLACEMENT_BASE_DELAY_MS + Math.floor(unit * FRESH_SANDBOX_READINESS_REPLACEMENT_JITTER_MS);
5214
+ }
5215
+ var FRESH_SANDBOX_READINESS_REPLACEMENTS_PER_TURN_ATTEMPT = 1;
5216
+ function createFreshSandboxReadinessReplacementBudget() {
5217
+ return { remaining: FRESH_SANDBOX_READINESS_REPLACEMENTS_PER_TURN_ATTEMPT };
5218
+ }
5219
+ function recordFreshSandboxReadinessReplacement(metrics, backend, outcome) {
5220
+ try {
5221
+ metrics?.onSandboxReadinessReplacement?.({ backend, outcome });
5222
+ } catch {
5223
+ }
5224
+ }
5225
+ async function sleepUnlessCancelled(ms, signal) {
5226
+ if (signal?.aborted) return false;
5227
+ if (ms <= 0) return true;
5228
+ return await new Promise((resolve) => {
5229
+ const onAbort = () => {
5230
+ clearTimeout(timer);
5231
+ resolve(false);
5232
+ };
5233
+ const timer = setTimeout(() => {
5234
+ signal?.removeEventListener("abort", onAbort);
5235
+ resolve(true);
5236
+ }, ms);
5237
+ signal?.addEventListener("abort", onAbort, { once: true });
5238
+ });
5239
+ }
5194
5240
  var SandboxLeaseInstanceLostError = class extends SandboxLeaseSupersededError {
5195
5241
  constructor(sandboxGroupId, leaseEpoch, lostInstanceId) {
5196
5242
  super(sandboxGroupId, leaseEpoch);
@@ -5640,6 +5686,69 @@ async function persistWarmWorkspaceSnapshot(services, ids, session, leaseEpoch,
5640
5686
  }
5641
5687
  }
5642
5688
  async function resumeBoxForTurn(services, ids, kind, holderId) {
5689
+ try {
5690
+ return await resumeBoxForTurnOnce(services, ids, kind, holderId);
5691
+ } catch (error) {
5692
+ if (!isReplaceableFreshSandboxReadinessTimeout(error)) throw error;
5693
+ const readiness = error;
5694
+ const warn = (message, fields) => {
5695
+ if (services.observability) services.observability.warn(message, fields);
5696
+ else console.warn(message, fields);
5697
+ };
5698
+ const identity = {
5699
+ workspaceId: ids.workspaceId,
5700
+ sessionId: ids.sessionId,
5701
+ sandboxGroupId: ids.sandboxGroupId,
5702
+ backend: readiness.backend,
5703
+ instanceId: readiness.instanceId,
5704
+ readinessTimeoutMs: readiness.timeoutMs
5705
+ };
5706
+ const budget = services.freshSandboxReadinessReplacementBudget ?? createFreshSandboxReadinessReplacementBudget();
5707
+ if (budget.remaining <= 0) {
5708
+ recordFreshSandboxReadinessReplacement(
5709
+ services.sandboxMetrics,
5710
+ readiness.backend,
5711
+ "budget_spent"
5712
+ );
5713
+ warn(
5714
+ "sandbox command-readiness timed out on a fresh box; this turn attempt already used its replacement",
5715
+ identity
5716
+ );
5717
+ throw error;
5718
+ }
5719
+ budget.remaining -= 1;
5720
+ const delayMs = await (services.freshSandboxReadinessReplacementDelayMs ?? freshSandboxReadinessReplacementDelayMs)();
5721
+ warn("sandbox command-readiness timed out on a fresh box; replacing it once after jitter", {
5722
+ ...identity,
5723
+ replacementDelayMs: delayMs
5724
+ });
5725
+ if (!await sleepUnlessCancelled(delayMs, services.cancellationSignal)) {
5726
+ recordFreshSandboxReadinessReplacement(
5727
+ services.sandboxMetrics,
5728
+ readiness.backend,
5729
+ "cancelled"
5730
+ );
5731
+ throw error;
5732
+ }
5733
+ try {
5734
+ const replaced = await resumeBoxForTurnOnce(services, ids, kind, holderId);
5735
+ recordFreshSandboxReadinessReplacement(
5736
+ services.sandboxMetrics,
5737
+ readiness.backend,
5738
+ "replaced"
5739
+ );
5740
+ return replaced;
5741
+ } catch (replacementError) {
5742
+ recordFreshSandboxReadinessReplacement(
5743
+ services.sandboxMetrics,
5744
+ readiness.backend,
5745
+ services.cancellationSignal?.aborted ? "cancelled" : replacementError instanceof SandboxExecReadinessTimeoutError ? "failed_again" : "replacement_failed"
5746
+ );
5747
+ throw replacementError;
5748
+ }
5749
+ }
5750
+ }
5751
+ async function resumeBoxForTurnOnce(services, ids, kind, holderId) {
5643
5752
  const { db, settings } = services;
5644
5753
  const os = ids.os ?? "linux";
5645
5754
  const leaseTtlMs = settings.sandboxLeaseTtlMs;
@@ -6080,9 +6189,15 @@ async function resumeBoxForTurn(services, ids, kind, holderId) {
6080
6189
  });
6081
6190
  createdEstablished = established;
6082
6191
  throwIfReleasedOrCancelled();
6083
- await waitForSandboxExecReadiness(established, MODAL_EXEC_READINESS_TIMEOUT_MS, {
6084
- sandboxGroupId: ids.sandboxGroupId
6085
- });
6192
+ if (services.verifySpawnedSandboxReadiness) {
6193
+ await services.verifySpawnedSandboxReadiness(established, {
6194
+ sandboxGroupId: ids.sandboxGroupId
6195
+ });
6196
+ } else {
6197
+ await waitForSandboxExecReadiness(established, MODAL_EXEC_READINESS_TIMEOUT_MS, {
6198
+ sandboxGroupId: ids.sandboxGroupId
6199
+ });
6200
+ }
6086
6201
  await maybeRenewProviderExpiration(true);
6087
6202
  throwIfReleasedOrCancelled();
6088
6203
  const resumeEnvelope = requirePersistableReplacementSandboxEnvelope(
@@ -6176,6 +6291,9 @@ async function resumeBoxForTurn(services, ids, kind, holderId) {
6176
6291
  }
6177
6292
  await release();
6178
6293
  recordSandboxWarmingTimeout(services.sandboxMetrics, error);
6294
+ if (terminated && createdEstablished && error instanceof SandboxExecReadinessTimeoutError && error.instanceId === createdEstablished.instanceId && (createdEstablished.origin === "created" || createdEstablished.origin === "restored") && !createdEstablished.providerContinuity) {
6295
+ disposedUnreadyFreshSandboxErrors.add(error);
6296
+ }
6179
6297
  throw sandboxProvisionStageError(rematerialization ? "archive_recovery" : "create", error);
6180
6298
  }
6181
6299
  }
@@ -8696,6 +8814,9 @@ import {
8696
8814
  RoutingWorkspaceRootChangedError,
8697
8815
  SandboxMaterializationVerificationError,
8698
8816
  materializationVerificationDiagnostic,
8817
+ PROVIDER_QUOTA_EXHAUSTED_CODE,
8818
+ classifyProviderQuotaError,
8819
+ providerQuotaExhaustedMessage,
8699
8820
  SelfhostedWorkspaceRootChangedError,
8700
8821
  UNKNOWN_MODEL_FINISH_REASON_CODE
8701
8822
  } from "@opengeni/runtime";
@@ -9213,6 +9334,7 @@ function sandboxFilePath(resource, file) {
9213
9334
 
9214
9335
  // src/activities/agent-turn/errors.ts
9215
9336
  import {
9337
+ CODEX_USAGE_LIMIT_ERROR_TYPE,
9216
9338
  CodexReloginRequired,
9217
9339
  classifyCodexEncryptedArtifactRejection,
9218
9340
  classifyCodexResponseTimeoutError,
@@ -9496,6 +9618,12 @@ function compactionFailureReasonFromError(error) {
9496
9618
  `the model provider rejected the compaction request (${describeCompactionProviderRejection(rejection)}). Active history was preserved. ${COMPACTION_PROVIDER_REJECTION_GUIDANCE}`
9497
9619
  );
9498
9620
  }
9621
+ const quota = classifyProviderQuotaExhaustionError(error);
9622
+ if (quota) {
9623
+ return compactionFailureReason(
9624
+ `${providerQuotaExhaustedMessage(quota.scope)} Active history was preserved.`
9625
+ );
9626
+ }
9499
9627
  if (error instanceof CompactionProviderResponseError || error instanceof EmptyCompactionSummaryError) {
9500
9628
  return compactionFailureReason(error.message);
9501
9629
  }
@@ -9504,13 +9632,15 @@ function compactionFailureReasonFromError(error) {
9504
9632
  }
9505
9633
  function compactionFailureTurnEventPayload(error, overrides = {}) {
9506
9634
  const rejection = compactionProviderRejection(error);
9635
+ const quota = rejection ? null : classifyProviderQuotaExhaustionError(error);
9507
9636
  return {
9508
9637
  error: overrides.error ?? compactionFailureReasonFromError(error),
9509
9638
  code: "context_compaction_failed",
9510
9639
  retryable: false,
9511
9640
  recovery: "user_message",
9512
9641
  compacted: false,
9513
- ...rejection ? { providerRejection: rejection } : {}
9642
+ ...rejection ? { providerRejection: rejection } : {},
9643
+ ...quota ? { quotaScope: quota.scope } : {}
9514
9644
  };
9515
9645
  }
9516
9646
  function isCompactionSummaryFailure(error) {
@@ -9614,6 +9744,13 @@ function isTransientProviderError(error) {
9614
9744
  message
9615
9745
  );
9616
9746
  }
9747
+ function hasCodexUsageLimitType(error) {
9748
+ return collectErrorStrings(error).some((value) => value.includes(CODEX_USAGE_LIMIT_ERROR_TYPE));
9749
+ }
9750
+ function classifyProviderQuotaExhaustionError(error) {
9751
+ if (isCodexTransportError(error) || isXaiSubscriptionTransportError(error)) return null;
9752
+ return classifyProviderQuotaError(error);
9753
+ }
9617
9754
  function classifyXaiCredentialFailure(error) {
9618
9755
  if (isProviderSafetyRefusal(error)) return null;
9619
9756
  let relogin = error;
@@ -9790,7 +9927,7 @@ function baseAgentRunFailurePayload(error, options = {}) {
9790
9927
  };
9791
9928
  }
9792
9929
  const usageLimit = classifyCodexUsageLimitError(error);
9793
- if (usageLimit) {
9930
+ if (usageLimit && (isCodexTransportError(error) || hasCodexUsageLimitType(error))) {
9794
9931
  return codexUsageLimitFailurePayload(usageLimit, message);
9795
9932
  }
9796
9933
  const codexTimeout = classifyCodexResponseTimeoutError(error, {
@@ -9835,6 +9972,16 @@ function baseAgentRunFailurePayload(error, options = {}) {
9835
9972
  retryable: true
9836
9973
  };
9837
9974
  }
9975
+ const quota = classifyProviderQuotaExhaustionError(error);
9976
+ if (quota) {
9977
+ return {
9978
+ error: providerQuotaExhaustedMessage(quota.scope),
9979
+ code: PROVIDER_QUOTA_EXHAUSTED_CODE,
9980
+ retryable: false,
9981
+ quotaScope: quota.scope,
9982
+ ...message ? { detail: message } : {}
9983
+ };
9984
+ }
9838
9985
  if (status === 429 || code === "rate_limit_exceeded" || /(?:too many requests|rate.?limit|\b429\b)/i.test(message)) {
9839
9986
  return {
9840
9987
  error: "Model provider rate limit hit. Try again in a minute or lower the reasoning effort.",
@@ -9990,6 +10137,7 @@ export {
9990
10137
  persistWorkspaceArchiveCandidate,
9991
10138
  putVersion1TarArchiveOrInline,
9992
10139
  sandboxLeaseHolderIdForAttempt,
10140
+ createFreshSandboxReadinessReplacementBudget,
9993
10141
  waitForWarmSnapshot,
9994
10142
  maybePersistWarmWorkspaceSnapshot,
9995
10143
  resumeBoxForTurn,
@@ -10071,4 +10219,4 @@ export {
10071
10219
  codexUsageLimitFailurePayload,
10072
10220
  CODEX_USAGE_LIMIT_MAX_RESUME_MS
10073
10221
  };
10074
- //# sourceMappingURL=chunk-JMO5ZUW3.js.map
10222
+ //# sourceMappingURL=chunk-7M6G2SCF.js.map