@pattern-stack/codegen 0.17.0 → 0.17.2

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 (141) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/consumer-skills/integration/audit-and-detection.md +29 -4
  3. package/dist/{chunk-GJDEPTPY.js → chunk-235ZMMJR.js} +8 -8
  4. package/dist/{chunk-DTXH24LR.js → chunk-65MO75WM.js} +9 -9
  5. package/dist/{chunk-5RT7JGKT.js → chunk-7OVCARTQ.js} +4 -4
  6. package/dist/{chunk-CO6LUM72.js → chunk-7P5ODGLA.js} +34 -2
  7. package/dist/chunk-7P5ODGLA.js.map +1 -0
  8. package/dist/{chunk-P3AYBRP6.js → chunk-ATVGYF3D.js} +11 -5
  9. package/dist/chunk-ATVGYF3D.js.map +1 -0
  10. package/dist/{chunk-3MAZ4TQH.js → chunk-AZLUWG5S.js} +9 -9
  11. package/dist/{chunk-UTNWFHJF.js → chunk-B34G6PHD.js} +10 -10
  12. package/dist/{chunk-CDLWYZVQ.js → chunk-BHZP6LOV.js} +7 -7
  13. package/dist/{chunk-W2UIDI3R.js → chunk-CLWBNXKF.js} +4 -4
  14. package/dist/{chunk-OTR44OH6.js → chunk-E6PLM6QG.js} +34 -13
  15. package/dist/chunk-E6PLM6QG.js.map +1 -0
  16. package/dist/{chunk-43SBT72G.js → chunk-I6UXRJ3Q.js} +4 -4
  17. package/dist/{chunk-36U5UGIO.js → chunk-JEINYUJH.js} +8 -5
  18. package/dist/chunk-JEINYUJH.js.map +1 -0
  19. package/dist/{chunk-K2I6XIK5.js → chunk-KSTZIULO.js} +4 -4
  20. package/dist/{chunk-L3VJ47BU.js → chunk-KZDHMZ45.js} +6 -6
  21. package/dist/{chunk-RHYNACZS.js → chunk-OZEPJGMA.js} +2 -2
  22. package/dist/{chunk-MYQIQ27N.js → chunk-Q6LRJ4VI.js} +51 -2
  23. package/dist/chunk-Q6LRJ4VI.js.map +1 -0
  24. package/dist/{chunk-NXNVTXKG.js → chunk-R6F6KFIL.js} +5 -5
  25. package/dist/{chunk-7LKAMLV4.js → chunk-T6SCOJF4.js} +4 -4
  26. package/dist/{chunk-OGIZXGPY.js → chunk-TDEHU73T.js} +4 -4
  27. package/dist/{chunk-OITTYGJS.js → chunk-VDL5CJ5C.js} +24 -14
  28. package/dist/chunk-VDL5CJ5C.js.map +1 -0
  29. package/dist/{chunk-3VEVGL74.js → chunk-VNBC3VXM.js} +4 -4
  30. package/dist/{chunk-BULPAAD3.js → chunk-VQOAATIG.js} +42 -11
  31. package/dist/chunk-VQOAATIG.js.map +1 -0
  32. package/dist/{chunk-E45CSC33.js → chunk-XKWOJZZ4.js} +2 -2
  33. package/dist/{chunk-DCCZB4UC.js → chunk-XWBK3XJK.js} +4 -4
  34. package/dist/{chunk-4GLNY5V6.js → chunk-Y7GDG744.js} +5 -5
  35. package/dist/{chunk-SR7F3TJY.js → chunk-YK5JEVLX.js} +4 -4
  36. package/dist/{job-orchestrator.protocol-DubMVbm9.d.ts → job-orchestrator.protocol-ZuJ3ow-O.d.ts} +77 -3
  37. package/dist/runtime/base-classes/index.js +12 -12
  38. package/dist/runtime/shared/openapi/index.js +5 -5
  39. package/dist/runtime/shared/openapi/registry.js +2 -2
  40. package/dist/runtime/subsystems/auth/auth.module.js +3 -3
  41. package/dist/runtime/subsystems/auth/index.js +12 -12
  42. package/dist/runtime/subsystems/bridge/bridge-delivery-handler.d.ts +1 -1
  43. package/dist/runtime/subsystems/bridge/bridge-delivery-handler.js +3 -3
  44. package/dist/runtime/subsystems/bridge/bridge-delivery.drizzle-backend.js +3 -3
  45. package/dist/runtime/subsystems/bridge/bridge-outbox-drain-hook.js +7 -7
  46. package/dist/runtime/subsystems/bridge/bridge.module.d.ts +1 -1
  47. package/dist/runtime/subsystems/bridge/bridge.module.js +19 -19
  48. package/dist/runtime/subsystems/bridge/event-flow.service.d.ts +1 -1
  49. package/dist/runtime/subsystems/bridge/event-flow.service.js +2 -2
  50. package/dist/runtime/subsystems/bridge/index.d.ts +1 -1
  51. package/dist/runtime/subsystems/bridge/index.js +21 -21
  52. package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js +4 -4
  53. package/dist/runtime/subsystems/events/events.module.js +5 -5
  54. package/dist/runtime/subsystems/events/index.js +7 -7
  55. package/dist/runtime/subsystems/index.d.ts +1 -1
  56. package/dist/runtime/subsystems/index.js +100 -100
  57. package/dist/runtime/subsystems/integration/build-change-source.js +2 -2
  58. package/dist/runtime/subsystems/integration/deep-equal.differ.d.ts +19 -0
  59. package/dist/runtime/subsystems/integration/deep-equal.differ.js +1 -1
  60. package/dist/runtime/subsystems/integration/execute-integration.use-case.js +2 -2
  61. package/dist/runtime/subsystems/integration/index.js +39 -39
  62. package/dist/runtime/subsystems/integration/integration-cursor-store.drizzle-backend.js +2 -2
  63. package/dist/runtime/subsystems/integration/integration-run-recorder.drizzle-backend.js +2 -2
  64. package/dist/runtime/subsystems/integration/integration.module.d.ts +20 -0
  65. package/dist/runtime/subsystems/integration/integration.module.js +6 -6
  66. package/dist/runtime/subsystems/jobs/index.d.ts +1 -1
  67. package/dist/runtime/subsystems/jobs/index.js +27 -27
  68. package/dist/runtime/subsystems/jobs/job-handler.base.d.ts +1 -1
  69. package/dist/runtime/subsystems/jobs/job-handler.base.js +11 -3
  70. package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.d.ts +1 -1
  71. package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.js +6 -5
  72. package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.js.map +1 -1
  73. package/dist/runtime/subsystems/jobs/job-orchestrator.drizzle-backend.d.ts +1 -1
  74. package/dist/runtime/subsystems/jobs/job-orchestrator.drizzle-backend.js +3 -2
  75. package/dist/runtime/subsystems/jobs/job-orchestrator.memory-backend.d.ts +11 -1
  76. package/dist/runtime/subsystems/jobs/job-orchestrator.memory-backend.js +2 -2
  77. package/dist/runtime/subsystems/jobs/job-orchestrator.protocol.d.ts +1 -1
  78. package/dist/runtime/subsystems/jobs/job-run-keyset-cursor.d.ts +1 -1
  79. package/dist/runtime/subsystems/jobs/job-run-service.drizzle-backend.d.ts +1 -1
  80. package/dist/runtime/subsystems/jobs/job-run-service.drizzle-backend.js +2 -2
  81. package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.d.ts +1 -1
  82. package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.js +2 -2
  83. package/dist/runtime/subsystems/jobs/job-run-service.protocol.d.ts +1 -1
  84. package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.d.ts +1 -1
  85. package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js +1 -1
  86. package/dist/runtime/subsystems/jobs/job-worker.d.ts +9 -1
  87. package/dist/runtime/subsystems/jobs/job-worker.js +3 -3
  88. package/dist/runtime/subsystems/jobs/job-worker.module.d.ts +1 -1
  89. package/dist/runtime/subsystems/jobs/job-worker.module.js +11 -11
  90. package/dist/runtime/subsystems/jobs/jobs-domain.module.js +9 -9
  91. package/dist/runtime/subsystems/jobs/jobs-errors.d.ts +1 -1
  92. package/dist/runtime/subsystems/jobs/pg-notify.d.ts +25 -1
  93. package/dist/runtime/subsystems/jobs/pg-notify.js +1 -1
  94. package/dist/runtime/subsystems/observability/index.d.ts +1 -1
  95. package/dist/runtime/subsystems/observability/index.js +3 -3
  96. package/dist/runtime/subsystems/observability/observability.module.js +3 -3
  97. package/dist/runtime/subsystems/observability/observability.protocol.d.ts +1 -1
  98. package/dist/runtime/subsystems/observability/observability.service.d.ts +1 -1
  99. package/dist/runtime/subsystems/observability/observability.service.js +2 -2
  100. package/dist/runtime/subsystems/observability/reporters/bridge-metrics.reporter.d.ts +1 -1
  101. package/dist/runtime/subsystems/observability/reporters/index.d.ts +1 -1
  102. package/dist/runtime/subsystems/storage/index.js +1 -1
  103. package/dist/runtime/subsystems/storage/storage.module.js +1 -1
  104. package/dist/src/cli/index.js +38 -16
  105. package/dist/src/cli/index.js.map +1 -1
  106. package/dist/src/index.js +13 -13
  107. package/package.json +1 -1
  108. package/runtime/subsystems/integration/deep-equal.differ.ts +34 -5
  109. package/runtime/subsystems/integration/integration.module.ts +26 -2
  110. package/runtime/subsystems/jobs/job-handler.base.ts +115 -2
  111. package/runtime/subsystems/jobs/job-orchestrator.drizzle-backend.ts +43 -16
  112. package/runtime/subsystems/jobs/job-orchestrator.memory-backend.ts +58 -18
  113. package/runtime/subsystems/jobs/job-worker.ts +29 -11
  114. package/runtime/subsystems/jobs/pg-notify.ts +63 -3
  115. package/templates/subsystem/integration-config/codegen-config-integration-block.ejs.t +17 -0
  116. package/dist/chunk-36U5UGIO.js.map +0 -1
  117. package/dist/chunk-BULPAAD3.js.map +0 -1
  118. package/dist/chunk-CO6LUM72.js.map +0 -1
  119. package/dist/chunk-MYQIQ27N.js.map +0 -1
  120. package/dist/chunk-OITTYGJS.js.map +0 -1
  121. package/dist/chunk-OTR44OH6.js.map +0 -1
  122. package/dist/chunk-P3AYBRP6.js.map +0 -1
  123. /package/dist/{chunk-GJDEPTPY.js.map → chunk-235ZMMJR.js.map} +0 -0
  124. /package/dist/{chunk-DTXH24LR.js.map → chunk-65MO75WM.js.map} +0 -0
  125. /package/dist/{chunk-5RT7JGKT.js.map → chunk-7OVCARTQ.js.map} +0 -0
  126. /package/dist/{chunk-3MAZ4TQH.js.map → chunk-AZLUWG5S.js.map} +0 -0
  127. /package/dist/{chunk-UTNWFHJF.js.map → chunk-B34G6PHD.js.map} +0 -0
  128. /package/dist/{chunk-CDLWYZVQ.js.map → chunk-BHZP6LOV.js.map} +0 -0
  129. /package/dist/{chunk-W2UIDI3R.js.map → chunk-CLWBNXKF.js.map} +0 -0
  130. /package/dist/{chunk-43SBT72G.js.map → chunk-I6UXRJ3Q.js.map} +0 -0
  131. /package/dist/{chunk-K2I6XIK5.js.map → chunk-KSTZIULO.js.map} +0 -0
  132. /package/dist/{chunk-L3VJ47BU.js.map → chunk-KZDHMZ45.js.map} +0 -0
  133. /package/dist/{chunk-RHYNACZS.js.map → chunk-OZEPJGMA.js.map} +0 -0
  134. /package/dist/{chunk-NXNVTXKG.js.map → chunk-R6F6KFIL.js.map} +0 -0
  135. /package/dist/{chunk-7LKAMLV4.js.map → chunk-T6SCOJF4.js.map} +0 -0
  136. /package/dist/{chunk-OGIZXGPY.js.map → chunk-TDEHU73T.js.map} +0 -0
  137. /package/dist/{chunk-3VEVGL74.js.map → chunk-VNBC3VXM.js.map} +0 -0
  138. /package/dist/{chunk-E45CSC33.js.map → chunk-XKWOJZZ4.js.map} +0 -0
  139. /package/dist/{chunk-DCCZB4UC.js.map → chunk-XWBK3XJK.js.map} +0 -0
  140. /package/dist/{chunk-4GLNY5V6.js.map → chunk-Y7GDG744.js.map} +0 -0
  141. /package/dist/{chunk-SR7F3TJY.js.map → chunk-YK5JEVLX.js.map} +0 -0
@@ -11,6 +11,11 @@ import {
11
11
  JobTypeNotFoundError,
12
12
  MissingTenantIdError
13
13
  } from "./chunk-T4BIIU5E.js";
14
+ import {
15
+ FN_KEY_SENTINEL,
16
+ JobKeyFunctionUnavailableError,
17
+ keySelectorToTemplate
18
+ } from "./chunk-7P5ODGLA.js";
14
19
  import {
15
20
  JOBS_MULTI_TENANT
16
21
  } from "./chunk-ZPL74UQN.js";
@@ -98,8 +103,6 @@ var MemoryJobOrchestrator = class {
98
103
  * unit tests that want to seed the registry without NestJS.
99
104
  */
100
105
  registerHandler(type, meta, handlerClass) {
101
- const concurrencyKeyTemplate = meta.concurrency?.key ?? null;
102
- const dedupeKeyTemplate = meta.dedupe?.key ?? null;
103
106
  const dedupeWindowMs = meta.dedupe?.windowMs ?? null;
104
107
  const now = /* @__PURE__ */ new Date();
105
108
  const def = {
@@ -113,9 +116,13 @@ var MemoryJobOrchestrator = class {
113
116
  baseMs: 0
114
117
  },
115
118
  timeoutMs: meta.timeoutMs ?? null,
116
- concurrencyKeyTemplate: typeof concurrencyKeyTemplate === "string" ? concurrencyKeyTemplate : null,
119
+ concurrencyKeyTemplate: keySelectorToTemplate(
120
+ meta.concurrency?.key
121
+ ),
117
122
  collisionMode: meta.concurrency?.collisionMode ?? "queue",
118
- dedupeKeyTemplate: typeof dedupeKeyTemplate === "string" ? dedupeKeyTemplate : null,
123
+ dedupeKeyTemplate: keySelectorToTemplate(
124
+ meta.dedupe?.key
125
+ ),
119
126
  dedupeWindowMs,
120
127
  priorityDefault: 0,
121
128
  replayFrom: meta.replayFrom ?? "last_checkpoint",
@@ -133,6 +140,26 @@ var MemoryJobOrchestrator = class {
133
140
  getHandlerRegistration(type) {
134
141
  return this.handlerRegistry.get(type);
135
142
  }
143
+ /**
144
+ * JOB-FN-KEY (0.16.2): resolve a persisted key template against the payload.
145
+ * Delegates to the shared `resolveJobKey`, but binds the FUNCTION-sentinel
146
+ * lookup to THIS backend's local `handlerRegistry` (the memory backend keeps
147
+ * its own meta map seeded by `registerHandler`, distinct from the global
148
+ * `JOB_HANDLER_REGISTRY` that the Drizzle/worker path uses — memory tests
149
+ * register handlers directly, never via the `@JobHandler` decorator). The
150
+ * `evaluateTemplate` callback handles the ordinary `{{field}}` path.
151
+ */
152
+ resolveKey(kind, type, template, payload) {
153
+ if (template == null) return null;
154
+ if (template !== FN_KEY_SENTINEL) {
155
+ return evaluateKeyTemplate(template, payload);
156
+ }
157
+ const key = this.handlerRegistry.get(type)?.meta?.[kind]?.key;
158
+ if (typeof key !== "function") {
159
+ throw new JobKeyFunctionUnavailableError(type, kind);
160
+ }
161
+ return key(payload);
162
+ }
136
163
  /**
137
164
  * Boot-time upsert per `IJobOrchestrator.upsertJobRows`. Memory backend
138
165
  * just funnels each entry through `registerHandler`. The validator is
@@ -160,10 +187,7 @@ var MemoryJobOrchestrator = class {
160
187
  const definition = this.store.jobs.get(type);
161
188
  if (!definition) throw new JobTypeNotFoundError(type);
162
189
  if (definition.dedupeKeyTemplate && definition.dedupeWindowMs) {
163
- const dedupeKey2 = evaluateKeyTemplate(
164
- definition.dedupeKeyTemplate,
165
- payload
166
- );
190
+ const dedupeKey2 = this.resolveKey("dedupe", type, definition.dedupeKeyTemplate, payload);
167
191
  const windowStart = Date.now() - definition.dedupeWindowMs;
168
192
  const existing = this.findDedupeCandidate(type, dedupeKey2, windowStart);
169
193
  if (existing) return existing;
@@ -171,7 +195,9 @@ var MemoryJobOrchestrator = class {
171
195
  let concurrencyKey = null;
172
196
  let queueBlockedBy = null;
173
197
  if (definition.concurrencyKeyTemplate) {
174
- concurrencyKey = evaluateKeyTemplate(
198
+ concurrencyKey = this.resolveKey(
199
+ "concurrency",
200
+ type,
175
201
  definition.concurrencyKeyTemplate,
176
202
  payload
177
203
  );
@@ -204,7 +230,12 @@ var MemoryJobOrchestrator = class {
204
230
  }
205
231
  rootRunId = parent.rootRunId;
206
232
  }
207
- const dedupeKey = definition.dedupeKeyTemplate ? evaluateKeyTemplate(definition.dedupeKeyTemplate, payload) : null;
233
+ const dedupeKey = this.resolveKey(
234
+ "dedupe",
235
+ type,
236
+ definition.dedupeKeyTemplate,
237
+ payload
238
+ );
208
239
  const now = /* @__PURE__ */ new Date();
209
240
  const runAt = queueBlockedBy ? QUEUED_RUN_AT : opts.runAt ?? now;
210
241
  const row = {
@@ -632,4 +663,4 @@ function serialiseError(err, attempt, retryable) {
632
663
  export {
633
664
  MemoryJobOrchestrator
634
665
  };
635
- //# sourceMappingURL=chunk-BULPAAD3.js.map
666
+ //# sourceMappingURL=chunk-VQOAATIG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../runtime/subsystems/jobs/job-orchestrator.memory-backend.ts"],"sourcesContent":["/**\n * MemoryJobOrchestrator — in-process implementation of `IJobOrchestrator`\n * (ADR-022, JOB-4).\n *\n * Exists solely for the unit test suite: reproduces the Drizzle backend's\n * observable behaviour (claim ordering, collision modes, dedupe collapse,\n * memoization cache, replay row-clearing, cascade cancel) without a\n * database. Not production — the single-process mutex is a substitute for\n * Postgres' `FOR UPDATE SKIP LOCKED`; acceptable non-parity is listed in\n * `docs/specs/JOB-4.md` (fsync, query perf, multi-process claim).\n *\n * The `MemoryJobStore` is shared with `MemoryJobRunService` /\n * `MemoryJobStepService` — all three services mutate the same Maps under\n * the orchestrator's mutex.\n */\nimport { randomUUID } from 'node:crypto';\nimport { Inject, Injectable, Logger, Optional } from '@nestjs/common';\nimport { ModuleRef } from '@nestjs/core';\nimport type {\n JobDefinitionRow,\n JobRunRow,\n} from './job-orchestration.schema';\nimport type {\n CancelOptions,\n IJobOrchestrator,\n JobPoolDef,\n JobRun,\n JobUpsertEntry,\n StartOptions,\n} from './job-orchestrator.protocol';\nimport type {\n JobContext,\n JobHandlerBase,\n JobHandlerMeta,\n JobKeySelector,\n RetryPolicy,\n SpawnChildOptions,\n StepOptions,\n} from './job-handler.base';\nimport {\n ParentClosePolicy,\n keySelectorToTemplate,\n FN_KEY_SENTINEL,\n JobKeyFunctionUnavailableError,\n} from './job-handler.base';\nimport {\n JobCollisionError,\n JobNotReplayableError,\n JobTemplateFieldMissingError,\n JobTypeNotFoundError,\n MissingTenantIdError,\n} from './jobs-errors';\nimport { MemoryJobStore } from './memory-job-store';\nimport { MemoryJobStepService } from './job-step-service.memory-backend';\nimport { JOBS_MULTI_TENANT } from './jobs-domain.tokens';\n\n/**\n * Sentinel `run_at` for runs that lost the `queue` collision — they stay\n * unclaimable until the incumbent transitions terminal and the orchestrator\n * advances their `run_at` back to `now()`. Mirrors the Drizzle backend's\n * `claim-time gate` behaviour without requiring a separate claim query.\n */\nconst QUEUED_RUN_AT = new Date(8_640_000_000_000_000); // \"distant future\"\nconst TERMINAL_STATUSES: JobRunRow['status'][] = [\n 'completed',\n 'failed',\n 'timed_out',\n 'canceled',\n];\nconst DEDUPE_EXCLUDED_STATUSES: JobRunRow['status'][] = ['canceled', 'failed'];\nconst IN_FLIGHT_STATUSES: JobRunRow['status'][] = ['pending', 'running'];\n\nfunction isTerminal(status: JobRunRow['status']): boolean {\n return TERMINAL_STATUSES.includes(status);\n}\n\n/**\n * Mirror of `evaluateKeyTemplate` in the Drizzle backend. Kept private here\n * rather than exported so the memory backend has no dependency on the\n * Drizzle module.\n */\nfunction evaluateKeyTemplate(\n template: string,\n input: Record<string, unknown>,\n): string {\n return template.replace(\n /\\{\\{\\s*([a-zA-Z0-9_]+)\\s*\\}\\}/g,\n (_m, field: string) => {\n const value = input[field];\n if (value === undefined || value === null) {\n throw new JobTemplateFieldMissingError(template, field);\n }\n return String(value);\n },\n );\n}\n\n/**\n * Single-promise-chain mutex. Every mutating op on the store goes through\n * `run(...)` so two concurrent `start` calls observe the same sequential\n * consistency Postgres gives us via `FOR UPDATE SKIP LOCKED`. Error\n * swallowing on the chain pointer prevents one failed call from poisoning\n * the queue for subsequent callers.\n *\n * Kept private to this file on purpose — the spec explicitly forbids\n * exporting this; it exists only for the memory backend's internal\n * serialisation.\n */\nclass PromiseMutex {\n private queue: Promise<void> = Promise.resolve();\n\n async run<T>(fn: () => Promise<T>): Promise<T> {\n const next = this.queue.then(() => fn());\n // Swallow errors on the chain pointer so a throwing `fn` doesn't\n // permanently reject every future caller.\n this.queue = next.then(\n () => undefined,\n () => undefined,\n );\n return next;\n }\n}\n\n/** Handler registry entry — class + frozen metadata. */\ninterface HandlerRegistration {\n type: string;\n meta: JobHandlerMeta<unknown>;\n handlerClass: new (...args: unknown[]) => JobHandlerBase<unknown>;\n}\n\n@Injectable()\nexport class MemoryJobOrchestrator implements IJobOrchestrator {\n private readonly logger = new Logger(MemoryJobOrchestrator.name);\n private readonly mutex = new PromiseMutex();\n private readonly handlerRegistry = new Map<string, HandlerRegistration>();\n\n /**\n * `runId → dependent runId[]` — when a run with `concurrencyKey = K`\n * blocks on an incumbent, its id is added here under the incumbent's id.\n * On incumbent terminal transition we advance every dependent's `runAt`\n * back to `now()` so it becomes claimable.\n */\n private readonly queueBlockers = new Map<string, string[]>();\n\n constructor(\n // ADR-037 (package-mode DI): explicit `@Inject` tokens on every param —\n // the published bundle has no `design:paramtypes` metadata (built without\n // `emitDecoratorMetadata`), so by-type injection would resolve to\n // `undefined` in package mode. Class tokens (`MemoryJobStore`,\n // `MemoryJobStepService`, `ModuleRef`) are passed to `@Inject` explicitly.\n @Inject(MemoryJobStore) private readonly store: MemoryJobStore,\n @Inject(MemoryJobStepService) private readonly stepService: MemoryJobStepService,\n @Inject(JOBS_MULTI_TENANT) private readonly multiTenant: boolean,\n @Optional() @Inject(ModuleRef) private readonly moduleRef?: ModuleRef,\n ) {}\n\n /**\n * JOB-8 — mirror of the Drizzle backend's `resolveTenantId`. Returns the\n * value to stamp on `tenant_id` / compare against in memory predicates.\n * Off → always `null`. On + `undefined` → throw. On + `null`/string → pass.\n */\n private resolveTenantId(\n method: string,\n tenantId: string | null | undefined,\n ): string | null {\n if (!this.multiTenant) return null;\n if (tenantId === undefined) throw new MissingTenantIdError(method);\n return tenantId;\n }\n\n // ==========================================================================\n // registerHandler — replaces Drizzle's `job` table upsert\n // ==========================================================================\n\n /**\n * Populate the in-memory job definition row plus handler class lookup.\n * Called by `JobWorkerModule.onModuleInit` in memory mode, or directly by\n * unit tests that want to seed the registry without NestJS.\n */\n registerHandler<TInput>(\n type: string,\n meta: JobHandlerMeta<TInput>,\n handlerClass: new (...args: unknown[]) => JobHandlerBase<TInput>,\n ): void {\n // JOB-FN-KEY (0.16.2): mirror the Drizzle backend — collapse a function\n // key to `FN_KEY_SENTINEL` so the def row stays non-null (collision/dedupe\n // path engages); `start()` re-resolves the live fn from `handlerRegistry`.\n const dedupeWindowMs = meta.dedupe?.windowMs ?? null;\n const now = new Date();\n\n const def: JobDefinitionRow = {\n type,\n version: 1,\n pool: meta.pool ?? 'batch',\n scopeEntityType: meta.scope?.entity ?? null,\n retryPolicy: meta.retry ?? {\n attempts: 1,\n backoff: 'fixed',\n baseMs: 0,\n },\n timeoutMs: meta.timeoutMs ?? null,\n concurrencyKeyTemplate: keySelectorToTemplate(\n meta.concurrency?.key as JobKeySelector<unknown> | undefined,\n ),\n collisionMode:\n (meta.concurrency?.collisionMode as JobDefinitionRow['collisionMode']) ??\n 'queue',\n dedupeKeyTemplate: keySelectorToTemplate(\n meta.dedupe?.key as JobKeySelector<unknown> | undefined,\n ),\n dedupeWindowMs,\n priorityDefault: 0,\n replayFrom: meta.replayFrom ?? 'last_checkpoint',\n createdAt: now,\n updatedAt: now,\n };\n\n this.store.jobs.set(type, def);\n this.handlerRegistry.set(type, {\n type,\n meta: meta as JobHandlerMeta<unknown>,\n handlerClass: handlerClass as unknown as new (\n ...args: unknown[]\n ) => JobHandlerBase<unknown>,\n });\n }\n\n /** Test helper — look up a registered handler without exposing the map. */\n getHandlerRegistration(type: string): HandlerRegistration | undefined {\n return this.handlerRegistry.get(type);\n }\n\n /**\n * JOB-FN-KEY (0.16.2): resolve a persisted key template against the payload.\n * Delegates to the shared `resolveJobKey`, but binds the FUNCTION-sentinel\n * lookup to THIS backend's local `handlerRegistry` (the memory backend keeps\n * its own meta map seeded by `registerHandler`, distinct from the global\n * `JOB_HANDLER_REGISTRY` that the Drizzle/worker path uses — memory tests\n * register handlers directly, never via the `@JobHandler` decorator). The\n * `evaluateTemplate` callback handles the ordinary `{{field}}` path.\n */\n private resolveKey(\n kind: 'concurrency' | 'dedupe',\n type: string,\n template: string | null,\n payload: Record<string, unknown>,\n ): string | null {\n if (template == null) return null;\n if (template !== FN_KEY_SENTINEL) {\n return evaluateKeyTemplate(template, payload);\n }\n const key = (this.handlerRegistry.get(type)?.meta?.[kind] as\n | { key?: unknown }\n | undefined)?.key;\n if (typeof key !== 'function') {\n throw new JobKeyFunctionUnavailableError(type, kind);\n }\n return (key as (input: unknown) => string)(payload);\n }\n\n /**\n * Boot-time upsert per `IJobOrchestrator.upsertJobRows`. Memory backend\n * just funnels each entry through `registerHandler`. The validator is\n * skipped entirely in memory mode (Q4 resolution 2026-04-19), so the\n * orphaned list is always empty — there are no DB rows to compare against.\n */\n async upsertJobRows(\n entries: JobUpsertEntry[],\n poolConfig: ReadonlyMap<string, JobPoolDef>,\n ): Promise<{ orphaned: string[] }> {\n void poolConfig; // pool validation is the module's responsibility\n for (const entry of entries) {\n this.registerHandler(\n entry.type,\n entry.meta as JobHandlerMeta<unknown>,\n entry.handlerClass as new (...args: unknown[]) => JobHandlerBase<unknown>,\n );\n }\n return { orphaned: [] };\n }\n\n // ==========================================================================\n // start\n // ==========================================================================\n\n async start(\n type: string,\n input: unknown,\n opts: StartOptions = {},\n // BRIDGE-7: signature parity with Drizzle backend. The memory backend\n // has no real transactions (its \"atomic\" boundary is a process-wide\n // mutex acquired by the body below), so the parameter is intentionally\n // ignored. Accepting it lets EventFlowService unit tests exercise the\n // same code path without two stub orchestrators.\n _tx?: unknown,\n ): Promise<JobRun> {\n // JOB-8 — resolve tenant gate outside the mutex so the error throws\n // synchronously-ish from the caller's stack rather than via the mutex's\n // deferred chain (matches Drizzle backend's pre-transaction guard).\n const tenantId = this.resolveTenantId('start', opts.tenantId);\n\n return this.mutex.run(async () => {\n const payload = (input ?? {}) as Record<string, unknown>;\n const definition = this.store.jobs.get(type);\n if (!definition) throw new JobTypeNotFoundError(type);\n\n // 1. Dedupe — return existing non-excluded run within the window.\n // JOB-FN-KEY: `resolveKey` honors the `{{field}}` template AND a function\n // key persisted as `FN_KEY_SENTINEL` (re-resolved from `handlerRegistry`).\n if (definition.dedupeKeyTemplate && definition.dedupeWindowMs) {\n const dedupeKey = this.resolveKey('dedupe', type, definition.dedupeKeyTemplate, payload) as string;\n const windowStart = Date.now() - definition.dedupeWindowMs;\n const existing = this.findDedupeCandidate(type, dedupeKey, windowStart);\n if (existing) return existing;\n }\n\n // 2. Concurrency collision check.\n let concurrencyKey: string | null = null;\n let queueBlockedBy: string | null = null;\n if (definition.concurrencyKeyTemplate) {\n // Non-null cast: the branch guard proves the template is present.\n concurrencyKey = this.resolveKey(\n 'concurrency',\n type,\n definition.concurrencyKeyTemplate,\n payload,\n ) as string;\n const incumbent = this.findInFlightByConcurrencyKey(concurrencyKey);\n if (incumbent) {\n switch (definition.collisionMode) {\n case 'reject':\n throw new JobCollisionError(type, concurrencyKey, incumbent);\n case 'replace':\n // Cancel incumbent (cascading children). Must happen inside\n // the mutex — call the internal helper, not public `cancel()`\n // (public `cancel` would re-enter the mutex and deadlock).\n // Internal replace path sidesteps the tenant gate — it uses\n // the incumbent's own tenant (same concurrency key implies\n // same tenant in practice, but the gate is bypassed via\n // `incumbent.tenantId` to avoid accidental cross-tenant\n // MissingTenantIdError bubbling from the user's `start` call).\n this.cancelLocked(\n incumbent.id,\n { cascade: true, reason: 'replaced' },\n incumbent.tenantId,\n );\n break;\n case 'queue':\n queueBlockedBy = incumbent.id;\n break;\n }\n }\n }\n\n // 3. Resolve lineage.\n const newId = randomUUID();\n let rootRunId: string = newId;\n if (opts.parentRunId) {\n const parent = this.store.runs.get(opts.parentRunId);\n if (!parent) {\n throw new Error(\n `parentRunId ${opts.parentRunId} does not reference an existing job_run`,\n );\n }\n rootRunId = parent.rootRunId;\n }\n\n // 4. Compute dedupe key for the persisted row (separate from dedupe\n // short-circuit above — we store it even when no prior run matched\n // so future dedupe checks see it).\n const dedupeKey = this.resolveKey(\n 'dedupe',\n type,\n definition.dedupeKeyTemplate,\n payload,\n );\n\n const now = new Date();\n const runAt = queueBlockedBy\n ? QUEUED_RUN_AT\n : (opts.runAt ?? now);\n\n const row: JobRunRow = {\n id: newId,\n jobType: type,\n jobVersion: definition.version,\n parentRunId: opts.parentRunId ?? null,\n rootRunId,\n parentClosePolicy: opts.parentClosePolicy ?? 'terminate',\n scopeEntityType: opts.scope?.entityType ?? null,\n scopeEntityId: opts.scope?.entityId ?? null,\n tenantId,\n tags: opts.tags ?? {},\n pool: opts.pool ?? definition.pool,\n priority: opts.priority ?? definition.priorityDefault,\n concurrencyKey,\n dedupeKey,\n status: 'pending',\n input: payload,\n output: null,\n error: null,\n triggerSource: opts.triggerSource ?? 'manual',\n triggerRef: opts.triggerRef ?? null,\n runAt,\n startedAt: null,\n finishedAt: null,\n claimedAt: null,\n attempts: 0,\n waitKind: null,\n resumeToken: null,\n waitDeadline: null,\n createdAt: now,\n updatedAt: now,\n };\n\n this.store.runs.set(newId, row);\n if (queueBlockedBy) {\n const list = this.queueBlockers.get(queueBlockedBy) ?? [];\n list.push(newId);\n this.queueBlockers.set(queueBlockedBy, list);\n }\n return row;\n });\n }\n\n // ==========================================================================\n // cancel\n // ==========================================================================\n\n async cancel(runId: string, opts: CancelOptions = {}): Promise<void> {\n // JOB-8 — strict tenant gate outside the mutex (matches Drizzle path).\n const tenantId = this.resolveTenantId('cancel', opts.tenantId);\n await this.mutex.run(async () => {\n this.cancelLocked(runId, opts, tenantId);\n });\n }\n\n /**\n * Internal cancel that assumes the caller already holds the mutex.\n * Synchronous because all store ops are in-memory. Idempotent.\n *\n * `tenantForGate` is the already-validated tenant id (or `null`). When\n * non-null it gates the initial cancellation to that tenant's run; the\n * cascade step then sweeps descendants on the same `rootRunId` without\n * re-checking — children of a tenant-gated parent always share the\n * tenant (enforced at `start` time).\n */\n private cancelLocked(\n runId: string,\n opts: CancelOptions,\n tenantForGate: string | null,\n ): void {\n const run = this.store.runs.get(runId);\n if (!run) return;\n // JOB-8 — cross-tenant cancel is silent no-op.\n if (this.multiTenant && run.tenantId !== tenantForGate) return;\n if (isTerminal(run.status)) return;\n\n const now = new Date();\n\n // Collect descendants up front so Cancel-policy parents can wait on\n // children (their `finished_at` is set after children transition).\n const descendants =\n opts.cascade === false\n ? []\n : Array.from(this.store.runs.values()).filter(\n (r) =>\n r.rootRunId === run.rootRunId &&\n r.id !== runId &&\n !isTerminal(r.status),\n );\n\n // Group by policy stored on the child.\n const terminateChildren = descendants.filter(\n (d) => d.parentClosePolicy === ParentClosePolicy.Terminate,\n );\n const cancelChildren = descendants.filter(\n (d) => d.parentClosePolicy === ParentClosePolicy.Cancel,\n );\n // 'abandon' → do nothing.\n\n // Terminate policy: cancel children, then parent.\n for (const child of terminateChildren) {\n this.transitionToCanceled(child.id, now);\n }\n\n // Cancel policy: cancel children first, then parent (so parent's\n // finished_at is set only after children transitioned).\n for (const child of cancelChildren) {\n this.transitionToCanceled(child.id, now);\n }\n\n this.transitionToCanceled(runId, now);\n\n void opts.reason; // reserved for future audit logging\n }\n\n private transitionToCanceled(runId: string, at: Date): void {\n const run = this.store.runs.get(runId);\n if (!run) return;\n if (isTerminal(run.status)) return;\n const next: JobRunRow = {\n ...run,\n status: 'canceled',\n finishedAt: at,\n updatedAt: at,\n };\n this.store.runs.set(runId, next);\n this.unblockQueuedDependents(runId);\n }\n\n /**\n * When `runId` transitions to a terminal state, advance every dependent\n * `queue`-blocked run's `run_at` back to `now()` so `claimNext` picks\n * them up.\n */\n private unblockQueuedDependents(runId: string): void {\n const dependents = this.queueBlockers.get(runId);\n if (!dependents || dependents.length === 0) return;\n const now = new Date();\n for (const dep of dependents) {\n const depRun = this.store.runs.get(dep);\n if (!depRun) continue;\n if (depRun.status !== 'pending') continue;\n this.store.runs.set(dep, { ...depRun, runAt: now, updatedAt: now });\n }\n this.queueBlockers.delete(runId);\n }\n\n // ==========================================================================\n // claimNext — consumed by JobWorker in memory mode (tests exercise directly)\n // ==========================================================================\n\n async claimNext(pool: string): Promise<JobRunRow | null> {\n return this.mutex.run(async () => {\n const now = Date.now();\n const candidates = Array.from(this.store.runs.values()).filter(\n (r) =>\n r.status === 'pending' &&\n r.pool === pool &&\n r.runAt.getTime() <= now,\n );\n if (candidates.length === 0) return null;\n\n // ORDER BY priority DESC, run_at ASC (Drizzle parity).\n candidates.sort((a, b) => {\n if (a.priority !== b.priority) return b.priority - a.priority;\n return a.runAt.getTime() - b.runAt.getTime();\n });\n\n const winner = candidates[0]!;\n const claimedAt = new Date();\n const next: JobRunRow = {\n ...winner,\n status: 'running',\n claimedAt,\n startedAt: claimedAt,\n updatedAt: claimedAt,\n };\n this.store.runs.set(winner.id, next);\n return next;\n });\n }\n\n // ==========================================================================\n // replay\n // ==========================================================================\n\n async replay(runId: string): Promise<JobRun> {\n return this.mutex.run(async () => {\n const run = this.store.runs.get(runId);\n if (!run) throw new Error(`replay: run ${runId} not found`);\n if (!isTerminal(run.status)) {\n throw new JobNotReplayableError(runId, run.status);\n }\n const def = this.store.jobs.get(run.jobType);\n if (!def) throw new JobTypeNotFoundError(run.jobType);\n\n const mode = def.replayFrom;\n if (mode === 'scratch') {\n this.stepService.clearStepsForRun(runId);\n } else {\n // `last_step` and `last_checkpoint` collapse to the same semantic\n // in Phase 1 — delete non-completed rows, preserve memoized ones.\n // Matches the Drizzle backend exactly (see JOB-3 notes).\n this.stepService.clearIncompleteSteps(runId);\n }\n\n const now = new Date();\n const next: JobRunRow = {\n ...run,\n status: 'pending',\n attempts: 0,\n runAt: now,\n startedAt: null,\n finishedAt: null,\n claimedAt: null,\n error: null,\n output: null,\n updatedAt: now,\n };\n this.store.runs.set(runId, next);\n return next;\n });\n }\n\n // ==========================================================================\n // tick — used by unit tests + memory-mode JobWorker\n // ==========================================================================\n\n /**\n * Execute a single claimed run to completion, retry, or failure. Not on\n * `IJobOrchestrator` — it's the memory equivalent of the Drizzle\n * `JobWorker.processRun` code path. The unit tests drive it directly so\n * they can assert memoization across ticks without spinning up a worker.\n */\n async tick(runId: string): Promise<void> {\n // We load state outside the mutex because handler execution cannot\n // hold the serialisation lock — `fn()` inside `ctx.step` can call back\n // into `start` / `spawnChild` which would deadlock. Mutation points\n // (recordStep, status transition) go through the services or the\n // orchestrator entry points and re-enter the mutex there.\n const run = this.store.runs.get(runId);\n if (!run) throw new Error(`tick: run ${runId} not found`);\n if (run.status !== 'running') {\n throw new Error(\n `tick: run ${runId} must be 'running' (got '${run.status}')`,\n );\n }\n\n const registration = this.handlerRegistry.get(run.jobType);\n if (!registration) {\n await this.markFailed(run, new Error(\n `No handler registered for jobType='${run.jobType}'`,\n ), (run.attempts ?? 0) + 1);\n return;\n }\n const meta = registration.meta;\n const HandlerClass = registration.handlerClass;\n // Match the Drizzle backend: resolve the handler through Nest's\n // ModuleRef so `@Inject` constructor params work. ModuleRef is\n // @Optional() — zero-dep test stubs that construct this orchestrator\n // manually still hit the legacy `new HandlerClass()` path.\n // `get({ strict: false })` (not `create()`) — the handler must be a\n // provider in its owning module so cross-module @Inject dependencies\n // resolve. See job-worker.ts for the full rationale.\n const handler = this.moduleRef\n ? (this.moduleRef.get(\n HandlerClass as unknown as new (...args: unknown[]) => unknown,\n { strict: false },\n ) as JobHandlerBase<unknown>)\n : new HandlerClass();\n\n const ctx: JobContext<unknown> = {\n input: run.input,\n run: run as JobRun,\n step: this.makeStepFn(run),\n spawnChild: this.makeSpawnFn(run),\n logger: new Logger(`JobRun:${run.id}`),\n };\n\n const attemptsBefore = run.attempts ?? 0;\n try {\n const output = (await handler.run(ctx)) as Record<string, unknown> | undefined;\n await this.markCompleted(run, output ?? {}, attemptsBefore + 1);\n } catch (err) {\n const policy = meta.retry;\n const decision = classifyError(err, policy, attemptsBefore);\n const nextAttempts = attemptsBefore + 1;\n if (decision === 'retry' && policy) {\n const delay = computeBackoff(policy, nextAttempts);\n await this.rescheduleForRetry(run, err, nextAttempts, delay);\n } else {\n await this.markFailed(run, err, nextAttempts);\n }\n }\n }\n\n private makeStepFn(run: JobRunRow) {\n return async <TOutput>(\n stepId: string,\n fn: () => Promise<TOutput>,\n _opts?: StepOptions,\n ): Promise<TOutput> => {\n void _opts;\n const existing = await this.stepService.findStep(run.id, stepId);\n if (existing?.status === 'completed') {\n return existing.output as TOutput;\n }\n const seq = this.nextStepSeq(run.id);\n const startedAt = new Date();\n const nextAttempts = (existing?.attempts ?? 0) + 1;\n await this.stepService.recordStep({\n jobRunId: run.id,\n stepId,\n kind: 'task',\n seq,\n status: 'running',\n startedAt,\n attempts: nextAttempts,\n });\n try {\n const output = await fn();\n await this.stepService.recordStep({\n jobRunId: run.id,\n stepId,\n kind: 'task',\n seq,\n status: 'completed',\n output: output as Record<string, unknown> | undefined,\n finishedAt: new Date(),\n attempts: nextAttempts,\n });\n return output;\n } catch (err) {\n await this.stepService.recordStep({\n jobRunId: run.id,\n stepId,\n kind: 'task',\n seq,\n status: 'failed',\n error: serialiseError(err, nextAttempts, false),\n finishedAt: new Date(),\n attempts: nextAttempts,\n });\n throw err;\n }\n };\n }\n\n private makeSpawnFn(run: JobRunRow) {\n return async (\n type: string,\n input: unknown,\n opts?: SpawnChildOptions,\n ): Promise<JobRun> => {\n return this.start(type, input, {\n parentRunId: run.id,\n parentClosePolicy: opts?.closePolicy,\n runAt: opts?.runAt,\n priority: opts?.priority,\n tags: opts?.tags,\n triggerSource: 'parent',\n triggerRef: run.id,\n });\n };\n }\n\n private nextStepSeq(runId: string): number {\n const rows = this.store.steps.get(runId);\n if (!rows || rows.length === 0) return 1;\n let max = 0;\n for (const r of rows) if (r.seq > max) max = r.seq;\n return max + 1;\n }\n\n private async markCompleted(\n run: JobRunRow,\n output: Record<string, unknown>,\n attempts: number,\n ): Promise<void> {\n await this.mutex.run(async () => {\n const current = this.store.runs.get(run.id);\n if (!current || isTerminal(current.status)) return;\n const now = new Date();\n this.store.runs.set(run.id, {\n ...current,\n status: 'completed',\n output,\n finishedAt: now,\n updatedAt: now,\n attempts,\n });\n this.unblockQueuedDependents(run.id);\n });\n }\n\n private async markFailed(\n run: JobRunRow,\n err: unknown,\n attempts: number,\n ): Promise<void> {\n await this.mutex.run(async () => {\n const current = this.store.runs.get(run.id);\n if (!current || isTerminal(current.status)) return;\n const now = new Date();\n this.store.runs.set(run.id, {\n ...current,\n status: 'failed',\n finishedAt: now,\n updatedAt: now,\n attempts,\n error: serialiseError(err, attempts, false),\n });\n this.unblockQueuedDependents(run.id);\n });\n\n // parent_close_policy = 'terminate' cascade mirrors the Drizzle worker\n // (cancel runs outside its own terminal transition). We pass the run's\n // own `tenantId` so the cancel passes the multi-tenant gate — this is\n // system-internal cascade, not a user-initiated call.\n if (run.parentClosePolicy === 'terminate') {\n try {\n await this.cancel(run.id, {\n cascade: true,\n reason: 'parent-failed',\n tenantId: run.tenantId,\n });\n } catch (cascadeErr) {\n this.logger.warn(\n `cascade on failed run ${run.id}: ${(cascadeErr as Error).message}`,\n );\n }\n }\n }\n\n private async rescheduleForRetry(\n run: JobRunRow,\n err: unknown,\n attempts: number,\n delayMs: number,\n ): Promise<void> {\n await this.mutex.run(async () => {\n const current = this.store.runs.get(run.id);\n if (!current || isTerminal(current.status)) return;\n const now = new Date();\n this.store.runs.set(run.id, {\n ...current,\n status: 'pending',\n attempts,\n runAt: new Date(Date.now() + delayMs),\n startedAt: null,\n claimedAt: null,\n updatedAt: now,\n error: serialiseError(err, attempts, true),\n });\n });\n }\n\n // ==========================================================================\n // Internal queries — used by start / cancel\n // ==========================================================================\n\n private findDedupeCandidate(\n jobType: string,\n dedupeKey: string,\n windowStartMs: number,\n ): JobRunRow | null {\n let best: JobRunRow | null = null;\n for (const r of this.store.runs.values()) {\n if (r.jobType !== jobType) continue;\n if (r.dedupeKey !== dedupeKey) continue;\n if (DEDUPE_EXCLUDED_STATUSES.includes(r.status)) continue;\n if (r.createdAt.getTime() <= windowStartMs) continue;\n if (!best || r.createdAt.getTime() > best.createdAt.getTime()) {\n best = r;\n }\n }\n return best;\n }\n\n private findInFlightByConcurrencyKey(key: string): JobRunRow | null {\n for (const r of this.store.runs.values()) {\n if (r.concurrencyKey !== key) continue;\n if (!IN_FLIGHT_STATUSES.includes(r.status)) continue;\n return r;\n }\n return null;\n }\n}\n\n// ─── Pure helpers (mirrored from JobWorker so memory mode is standalone) ────\n\nfunction classifyError(\n err: unknown,\n policy: RetryPolicy | undefined,\n currentAttempts: number,\n): 'retry' | 'fail' {\n if (!policy) return 'fail';\n const errObj = err as { name?: string; code?: string } | undefined;\n const name = errObj?.name;\n const code = errObj?.code;\n const nonRetryable = policy.nonRetryableErrors ?? [];\n if (nonRetryable.some((n) => n === name || n === code)) return 'fail';\n if (currentAttempts + 1 >= policy.attempts) return 'fail';\n return 'retry';\n}\n\nfunction computeBackoff(policy: RetryPolicy, attempts: number): number {\n const base = Math.max(policy.baseMs, 0);\n if (policy.backoff === 'fixed') return base;\n const exponent = Math.max(attempts - 1, 0);\n if (exponent >= 53) return Number.MAX_SAFE_INTEGER;\n const raw = base * Math.pow(2, exponent);\n if (!Number.isFinite(raw) || raw >= Number.MAX_SAFE_INTEGER) {\n return Number.MAX_SAFE_INTEGER;\n }\n return raw;\n}\n\nfunction serialiseError(err: unknown, attempt: number, retryable: boolean) {\n const e = err as { message?: string; stack?: string } | undefined;\n return {\n message: (e?.message ?? String(err)) as string,\n stack: e?.stack,\n retryable,\n attempt,\n };\n}\n"],"mappings":"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","names":["dedupeKey"]}
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-AQFQ4BYM.js";
4
4
  import {
5
5
  ObservabilityService
6
- } from "./chunk-W2UIDI3R.js";
6
+ } from "./chunk-CLWBNXKF.js";
7
7
  import {
8
8
  OBSERVABILITY,
9
9
  OBSERVABILITY_MODULE_OPTIONS
@@ -45,4 +45,4 @@ ObservabilityModule = __decorateClass([
45
45
  export {
46
46
  ObservabilityModule
47
47
  };
48
- //# sourceMappingURL=chunk-E45CSC33.js.map
48
+ //# sourceMappingURL=chunk-XKWOJZZ4.js.map
@@ -1,12 +1,12 @@
1
+ import {
2
+ INTEGRATION_MULTI_TENANT
3
+ } from "./chunk-S7C6TIIF.js";
1
4
  import {
2
5
  assertTenantId
3
6
  } from "./chunk-MZ6GV4YF.js";
4
7
  import {
5
8
  integrationSubscriptions
6
9
  } from "./chunk-HNWZFNKP.js";
7
- import {
8
- INTEGRATION_MULTI_TENANT
9
- } from "./chunk-S7C6TIIF.js";
10
10
  import {
11
11
  DRIZZLE
12
12
  } from "./chunk-U64T4YZE.js";
@@ -97,4 +97,4 @@ PostgresCursorStore = __decorateClass([
97
97
  export {
98
98
  PostgresCursorStore
99
99
  };
100
- //# sourceMappingURL=chunk-DCCZB4UC.js.map
100
+ //# sourceMappingURL=chunk-XWBK3XJK.js.map
@@ -1,11 +1,11 @@
1
- import {
2
- DuplicateSchemaError,
3
- OpenApiPeerDepMissingError
4
- } from "./chunk-YSLTTQLC.js";
5
1
  import {
6
2
  ERROR_RESPONSE_SCHEMA_NAME,
7
3
  errorResponseSchema
8
4
  } from "./chunk-SOVM2VEK.js";
5
+ import {
6
+ DuplicateSchemaError,
7
+ OpenApiPeerDepMissingError
8
+ } from "./chunk-YSLTTQLC.js";
9
9
 
10
10
  // runtime/shared/openapi/registry.ts
11
11
  var OpenApiRegistry = class {
@@ -85,4 +85,4 @@ var OpenApiRegistry = class {
85
85
  export {
86
86
  OpenApiRegistry
87
87
  };
88
- //# sourceMappingURL=chunk-4GLNY5V6.js.map
88
+ //# sourceMappingURL=chunk-Y7GDG744.js.map
@@ -1,6 +1,9 @@
1
1
  import {
2
2
  FieldDiffSchema
3
3
  } from "./chunk-SQDOBLBP.js";
4
+ import {
5
+ INTEGRATION_MULTI_TENANT
6
+ } from "./chunk-S7C6TIIF.js";
4
7
  import {
5
8
  assertTenantId
6
9
  } from "./chunk-MZ6GV4YF.js";
@@ -9,9 +12,6 @@ import {
9
12
  integrationRuns,
10
13
  integrationSubscriptions
11
14
  } from "./chunk-HNWZFNKP.js";
12
- import {
13
- INTEGRATION_MULTI_TENANT
14
- } from "./chunk-S7C6TIIF.js";
15
15
  import {
16
16
  DRIZZLE
17
17
  } from "./chunk-U64T4YZE.js";
@@ -127,4 +127,4 @@ DrizzleIntegrationRunRecorder = __decorateClass([
127
127
  export {
128
128
  DrizzleIntegrationRunRecorder
129
129
  };
130
- //# sourceMappingURL=chunk-SR7F3TJY.js.map
130
+ //# sourceMappingURL=chunk-YK5JEVLX.js.map
@@ -36,12 +36,31 @@ interface RetryPolicy {
36
36
  baseMs: number;
37
37
  nonRetryableErrors?: string[];
38
38
  }
39
+ /**
40
+ * Concurrency lane key (JOB-FN-KEY, 0.16.2).
41
+ *
42
+ * Two authoring forms, both honored end-to-end (the typed function form was
43
+ * previously dropped to `null` at registration — see `upsertJobRows` — so
44
+ * `collisionMode` silently never engaged):
45
+ *
46
+ * - **`string`** — a `{{field}}` template evaluated against the start
47
+ * payload by `evaluateKeyTemplate` (single-key substitution, no dotted
48
+ * paths). Persisted verbatim to `job.concurrency_key_template`.
49
+ * - **`(input) => string`** — an arbitrary function of the input. Persisted
50
+ * as the `FN_KEY_SENTINEL` marker so the definition-hash gate stays stable
51
+ * and the collision path engages; `start()` re-resolves the live function
52
+ * from `JOB_HANDLER_REGISTRY` and evaluates it against the payload.
53
+ *
54
+ * Both forms produce a per-lane key; same key + in-flight incumbent ⇒
55
+ * `collisionMode` ('queue' | 'reject' | 'replace') decides.
56
+ */
57
+ type JobKeySelector<TInput> = string | ((input: TInput) => string);
39
58
  interface ConcurrencyPolicy<TInput> {
40
- key: (input: TInput) => string;
59
+ key: JobKeySelector<TInput>;
41
60
  collisionMode: 'queue' | 'reject' | 'replace';
42
61
  }
43
62
  interface DedupePolicy<TInput> {
44
- key: (input: TInput) => string;
63
+ key: JobKeySelector<TInput>;
45
64
  windowMs: number;
46
65
  }
47
66
  /**
@@ -165,6 +184,61 @@ declare namespace HandlerRegistry {
165
184
  /** Lookup by job type, or `undefined` if no `@JobHandler` is registered. */
166
185
  function get(type: string): HandlerRegistryEntry | undefined;
167
186
  }
187
+ /**
188
+ * Sentinel persisted to `job.concurrency_key_template` / `dedupe_key_template`
189
+ * when the authored `key` is a function rather than a `{{field}}` template.
190
+ *
191
+ * Why a sentinel (not `null`): the collision/dedupe paths in both backends gate
192
+ * on `definition.concurrencyKeyTemplate != null`. A function key persisted as
193
+ * `null` (the pre-0.16.2 bug) left those columns empty, so `collisionMode` /
194
+ * the dedupe window never engaged — the job ran with NO key. A stable sentinel
195
+ * keeps the column non-null (path engages) AND keeps the definition-hash gate
196
+ * (`upsertJobRows`' `IS DISTINCT FROM` clause) stable across boots, since the
197
+ * function identity itself can't be hashed. `start()` detects the sentinel and
198
+ * re-resolves the live function from `JOB_HANDLER_REGISTRY`.
199
+ *
200
+ * Chosen as an angle-bracketed token so it can never collide with a real
201
+ * `{{field}}` template (which never contains a literal `<`).
202
+ */
203
+ declare const FN_KEY_SENTINEL = "<fn>";
204
+ /**
205
+ * Registration-time projection: collapse an authored `JobKeySelector` to the
206
+ * string stored in the `job` definition row. A string template is stored
207
+ * verbatim; a function is stored as `FN_KEY_SENTINEL`; absence stays `null`.
208
+ */
209
+ declare function keySelectorToTemplate(key: JobKeySelector<unknown> | undefined): string | null;
210
+ /** Which meta policy a key belongs to — selects the live fn at `start()`. */
211
+ type KeyKind = 'concurrency' | 'dedupe';
212
+ /**
213
+ * `start()`-time resolution shared by every backend. Turns the persisted
214
+ * template column into the concrete per-run key for the given payload.
215
+ *
216
+ * - `template == null` → `null` (no key; caller skips the collision/dedupe path).
217
+ * - `template === FN_KEY_SENTINEL` → look the live `@JobHandler` meta up in
218
+ * `JOB_HANDLER_REGISTRY`, pull `meta[kind].key`, and invoke it against the
219
+ * payload. The registry is the runtime source of truth (the worker already
220
+ * resolves handler classes the same way), so the function survives the DB
221
+ * round-trip even though it can't be persisted.
222
+ * - otherwise → a `{{field}}` template, evaluated via the injected
223
+ * `evaluateTemplate` (each backend passes its own copy to avoid a runtime
224
+ * import cycle).
225
+ *
226
+ * Throws `JobKeyFunctionUnavailableError` if the sentinel is present but no
227
+ * live function can be found (e.g. the registry was reset, or a function key
228
+ * was persisted by a newer build and read by an older one). Failing loud beats
229
+ * silently degrading to no-key — the exact regression this fix exists to kill.
230
+ */
231
+ declare function resolveJobKey(kind: KeyKind, type: string, template: string | null, payload: Record<string, unknown>, evaluateTemplate: (template: string, payload: Record<string, unknown>) => string): string | null;
232
+ /**
233
+ * Raised when a `${FN_KEY_SENTINEL}` template is read but the live function
234
+ * key is missing from `JOB_HANDLER_REGISTRY`. Kept here (not in `jobs-errors`)
235
+ * so `job-handler.base` stays import-cycle-free.
236
+ */
237
+ declare class JobKeyFunctionUnavailableError extends Error {
238
+ readonly jobType: string;
239
+ readonly kind: KeyKind;
240
+ constructor(jobType: string, kind: KeyKind);
241
+ }
168
242
 
169
243
  /**
170
244
  * Public return type for orchestrator reads. Re-exported as `JobRun` so
@@ -310,4 +384,4 @@ interface IJobOrchestrator {
310
384
  }>;
311
385
  }
312
386
 
313
- export { type CancelOptions as C, type DedupePolicy as D, HandlerRegistry as H, type IJobOrchestrator as I, JOB_HANDLER_METADATA_KEY as J, ParentClosePolicy as P, type RetryPolicy as R, type ScopeRef as S, type ConcurrencyPolicy as a, type HandlerRegistryEntry as b, JOB_HANDLER_REGISTRY as c, type JobContext as d, JobHandler as e, JobHandlerBase as f, type JobHandlerMeta as g, type JobPoolDef as h, type JobRun as i, type JobUpsertEntry as j, type SpawnChildOptions as k, type StartOptions as l, type StepOptions as m, type JobTrigger as n };
387
+ export { type CancelOptions as C, type DedupePolicy as D, FN_KEY_SENTINEL as F, HandlerRegistry as H, type IJobOrchestrator as I, JOB_HANDLER_METADATA_KEY as J, type KeyKind as K, ParentClosePolicy as P, type RetryPolicy as R, type ScopeRef as S, type ConcurrencyPolicy as a, type HandlerRegistryEntry as b, JOB_HANDLER_REGISTRY as c, type JobContext as d, JobHandler as e, JobHandlerBase as f, type JobHandlerMeta as g, type JobPoolDef as h, type JobRun as i, type JobUpsertEntry as j, type SpawnChildOptions as k, type StartOptions as l, type StepOptions as m, JobKeyFunctionUnavailableError as n, type JobKeySelector as o, type JobTrigger as p, keySelectorToTemplate as q, resolveJobKey as r };
@@ -1,6 +1,3 @@
1
- import {
2
- MetadataEntityRepository
3
- } from "../../chunk-7KOW6PU6.js";
4
1
  import {
5
2
  MetadataEntityService
6
3
  } from "../../chunk-RFH7N6EP.js";
@@ -24,6 +21,9 @@ import {
24
21
  import {
25
22
  KnowledgeEntityService
26
23
  } from "../../chunk-AS3NAZB6.js";
24
+ import {
25
+ MetadataEntityRepository
26
+ } from "../../chunk-7KOW6PU6.js";
27
27
  import {
28
28
  ActivityEntityRepository
29
29
  } from "../../chunk-MKWQKKK7.js";
@@ -37,6 +37,15 @@ import {
37
37
  import {
38
38
  BaseRepository
39
39
  } from "../../chunk-J6KZS54B.js";
40
+ import {
41
+ requireRequester,
42
+ requireRequesterScope,
43
+ tryGetRequester,
44
+ withOrgScope,
45
+ withRequester,
46
+ withSuperuserScope,
47
+ withUserScope
48
+ } from "../../chunk-ZUKFQL6E.js";
40
49
  import {
41
50
  BaseService
42
51
  } from "../../chunk-W72PRNJY.js";
@@ -47,15 +56,6 @@ import {
47
56
  emitSafely,
48
57
  entitySnapshot
49
58
  } from "../../chunk-KYR3B3OW.js";
50
- import {
51
- requireRequester,
52
- requireRequesterScope,
53
- tryGetRequester,
54
- withOrgScope,
55
- withRequester,
56
- withSuperuserScope,
57
- withUserScope
58
- } from "../../chunk-ZUKFQL6E.js";
59
59
  import "../../chunk-2E224ZSN.js";
60
60
  export {
61
61
  ActivityEntityRepository,
@@ -3,15 +3,15 @@ import {
3
3
  } from "../../../chunk-PSXUNOVU.js";
4
4
  import {
5
5
  OpenApiRegistry
6
- } from "../../../chunk-4GLNY5V6.js";
7
- import {
8
- DuplicateSchemaError,
9
- OpenApiPeerDepMissingError
10
- } from "../../../chunk-YSLTTQLC.js";
6
+ } from "../../../chunk-Y7GDG744.js";
11
7
  import {
12
8
  ERROR_RESPONSE_SCHEMA_NAME,
13
9
  errorResponseSchema
14
10
  } from "../../../chunk-SOVM2VEK.js";
11
+ import {
12
+ DuplicateSchemaError,
13
+ OpenApiPeerDepMissingError
14
+ } from "../../../chunk-YSLTTQLC.js";
15
15
  import "../../../chunk-2E224ZSN.js";
16
16
  export {
17
17
  DuplicateSchemaError,
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  OpenApiRegistry
3
- } from "../../../chunk-4GLNY5V6.js";
4
- import "../../../chunk-YSLTTQLC.js";
3
+ } from "../../../chunk-Y7GDG744.js";
5
4
  import "../../../chunk-SOVM2VEK.js";
5
+ import "../../../chunk-YSLTTQLC.js";
6
6
  import "../../../chunk-2E224ZSN.js";
7
7
  export {
8
8
  OpenApiRegistry
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  AuthModule
3
- } from "../../../chunk-7LKAMLV4.js";
3
+ } from "../../../chunk-T6SCOJF4.js";
4
4
  import "../../../chunk-IP4OO26U.js";
5
+ import "../../../chunk-SZVPIHWE.js";
5
6
  import "../../../chunk-N5OTOWTP.js";
6
7
  import "../../../chunk-QLTJSCE6.js";
7
8
  import "../../../chunk-BPARRK6F.js";
8
- import "../../../chunk-SZVPIHWE.js";
9
- import "../../../chunk-6XY6ZMMD.js";
10
9
  import "../../../chunk-NPFPZ2HO.js";
10
+ import "../../../chunk-6XY6ZMMD.js";
11
11
  import "../../../chunk-GYGNEQSC.js";
12
12
  import "../../../chunk-U64T4YZE.js";
13
13
  import "../../../chunk-2E224ZSN.js";
@@ -1,4 +1,9 @@
1
1
  import "../../../chunk-7C3FOSDI.js";
2
+ import {
3
+ installRequesterContext,
4
+ makeRequesterContextMiddleware,
5
+ resolveRequesterContext
6
+ } from "../../../chunk-OSQRXVG2.js";
2
7
  import {
3
8
  OAuth2RefreshStrategy
4
9
  } from "../../../chunk-M6QLSLPO.js";
@@ -12,17 +17,15 @@ import {
12
17
  SessionExpiredError,
13
18
  isSessionExpiredError
14
19
  } from "../../../chunk-7RELQJIN.js";
15
- import {
16
- installRequesterContext,
17
- makeRequesterContextMiddleware,
18
- resolveRequesterContext
19
- } from "../../../chunk-OSQRXVG2.js";
20
20
  import {
21
21
  AuthModule
22
- } from "../../../chunk-7LKAMLV4.js";
22
+ } from "../../../chunk-T6SCOJF4.js";
23
23
  import {
24
24
  EnvEncryptionKey
25
25
  } from "../../../chunk-IP4OO26U.js";
26
+ import {
27
+ AuthController
28
+ } from "../../../chunk-SZVPIHWE.js";
26
29
  import {
27
30
  DrizzleOAuthStateStore
28
31
  } from "../../../chunk-N5OTOWTP.js";
@@ -33,8 +36,8 @@ import {
33
36
  OAuthStateError
34
37
  } from "../../../chunk-BPARRK6F.js";
35
38
  import {
36
- AuthController
37
- } from "../../../chunk-SZVPIHWE.js";
39
+ authOAuthState
40
+ } from "../../../chunk-NPFPZ2HO.js";
38
41
  import {
39
42
  AUTH_CONNECTION_GRANT_SINK,
40
43
  AUTH_CONNECTION_READER,
@@ -45,12 +48,9 @@ import {
45
48
  OAUTH_STATE_STORE,
46
49
  STRATEGY_REGISTRY
47
50
  } from "../../../chunk-6XY6ZMMD.js";
48
- import {
49
- authOAuthState
50
- } from "../../../chunk-NPFPZ2HO.js";
51
51
  import "../../../chunk-GYGNEQSC.js";
52
- import "../../../chunk-ZUKFQL6E.js";
53
52
  import "../../../chunk-U64T4YZE.js";
53
+ import "../../../chunk-ZUKFQL6E.js";
54
54
  import "../../../chunk-2E224ZSN.js";
55
55
  export {
56
56
  AUTH_CONNECTION_GRANT_SINK,
@@ -1,4 +1,4 @@
1
- import { f as JobHandlerBase, I as IJobOrchestrator, d as JobContext } from '../../../job-orchestrator.protocol-DubMVbm9.js';
1
+ import { f as JobHandlerBase, I as IJobOrchestrator, d as JobContext } from '../../../job-orchestrator.protocol-ZuJ3ow-O.js';
2
2
  import { IEventBus } from '../events/event-bus.protocol.js';
3
3
  import { IJobBridge, BridgeRegistry } from './bridge.protocol.js';
4
4
  import '../jobs/job-orchestration.schema.js';
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  BRIDGE_DELIVERY_JOB_TYPE,
3
3
  BridgeDeliveryHandler
4
- } from "../../../chunk-NXNVTXKG.js";
4
+ } from "../../../chunk-R6F6KFIL.js";
5
5
  import "../../../chunk-6DWFJNIK.js";
6
6
  import "../../../chunk-NXXDZ6ZF.js";
7
- import "../../../chunk-CO6LUM72.js";
7
+ import "../../../chunk-7P5ODGLA.js";
8
8
  import "../../../chunk-ZPL74UQN.js";
9
- import "../../../chunk-4LH67P4U.js";
10
9
  import "../../../chunk-H5NH7KPE.js";
10
+ import "../../../chunk-4LH67P4U.js";
11
11
  import "../../../chunk-GYGNEQSC.js";
12
12
  import "../../../chunk-2E224ZSN.js";
13
13
  export {
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  DrizzleBridgeDeliveryRepo
3
- } from "../../../chunk-K2I6XIK5.js";
4
- import "../../../chunk-6DWFJNIK.js";
3
+ } from "../../../chunk-KSTZIULO.js";
5
4
  import "../../../chunk-2TVVBC53.js";
5
+ import "../../../chunk-6DWFJNIK.js";
6
6
  import "../../../chunk-NXXDZ6ZF.js";
7
- import "../../../chunk-OKXZ63IA.js";
8
7
  import "../../../chunk-4LH67P4U.js";
8
+ import "../../../chunk-OKXZ63IA.js";
9
9
  import "../../../chunk-OFRRBC7M.js";
10
10
  import "../../../chunk-U64T4YZE.js";
11
11
  import "../../../chunk-2E224ZSN.js";
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  BridgeOutboxDrainHook
3
- } from "../../../chunk-DTXH24LR.js";
4
- import "../../../chunk-NXNVTXKG.js";
5
- import "../../../chunk-6DWFJNIK.js";
3
+ } from "../../../chunk-65MO75WM.js";
4
+ import "../../../chunk-R6F6KFIL.js";
6
5
  import "../../../chunk-2TVVBC53.js";
6
+ import "../../../chunk-6DWFJNIK.js";
7
7
  import "../../../chunk-NXXDZ6ZF.js";
8
- import "../../../chunk-CO6LUM72.js";
8
+ import "../../../chunk-Q6LRJ4VI.js";
9
+ import "../../../chunk-7P5ODGLA.js";
9
10
  import "../../../chunk-ZPL74UQN.js";
10
- import "../../../chunk-OKXZ63IA.js";
11
- import "../../../chunk-MYQIQ27N.js";
11
+ import "../../../chunk-H5NH7KPE.js";
12
12
  import "../../../chunk-4LH67P4U.js";
13
+ import "../../../chunk-OKXZ63IA.js";
13
14
  import "../../../chunk-OFRRBC7M.js";
14
- import "../../../chunk-H5NH7KPE.js";
15
15
  import "../../../chunk-GYGNEQSC.js";
16
16
  import "../../../chunk-2E224ZSN.js";
17
17
  export {
@@ -7,7 +7,7 @@ import 'drizzle-orm/node-postgres';
7
7
  import '../jobs/jobs-domain.module.js';
8
8
  import '../jobs/bullmq.config.js';
9
9
  import '../jobs/pool-config.loader.js';
10
- import '../../../job-orchestrator.protocol-DubMVbm9.js';
10
+ import '../../../job-orchestrator.protocol-ZuJ3ow-O.js';
11
11
  import '../events/event-bus.protocol.js';
12
12
  import '../jobs/job-orchestration.schema.js';
13
13
  import 'drizzle-orm/pg-core';