@cmmd-center/forge 0.13.104 → 0.13.106

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.
package/dist/bin.cjs CHANGED
@@ -17846,6 +17846,7 @@ const OrchestrationThread = require_Schema$1.Struct({
17846
17846
  status: ThreadStatus.pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed("idle"))),
17847
17847
  workerRole: require_Schema$1.NullOr(WorkerRole).pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed(null))),
17848
17848
  workSessionId: require_Schema$1.optionalKey(require_Schema$1.NullOr(require_Schema$1.String)),
17849
+ workSessionBoundAt: require_Schema$1.optionalKey(require_Schema$1.NullOr(require_Schema$1.String)),
17849
17850
  pendingAutoCreatePrompt: require_Schema$1.optional(require_Schema$1.NullOr(AutoCreateTaskPrompt)).pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed(null))),
17850
17851
  goal: require_Schema$1.NullOr(TrimmedNonEmptyString).pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed(null))),
17851
17852
  titleRegeneration: require_Schema$1.NullOr(ThreadTitleRegeneration).pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed(null))),
@@ -18455,6 +18456,7 @@ const ThreadCreatedPayload$1 = require_Schema$1.Struct({
18455
18456
  anchorKind: CmmdAnchorKind.pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed("scratch"))),
18456
18457
  anchorCmmdId: require_Schema$1.NullOr(require_Schema$1.String).pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed(null))),
18457
18458
  workSessionId: require_Schema$1.optionalKey(require_Schema$1.NullOr(require_Schema$1.String)),
18459
+ workSessionBoundAt: require_Schema$1.optionalKey(require_Schema$1.NullOr(require_Schema$1.String)),
18458
18460
  goal: require_Schema$1.optionalKey(require_Schema$1.NullOr(TrimmedNonEmptyString)),
18459
18461
  linkedPullRequest: require_Schema$1.optionalKey(require_Schema$1.NullOr(LinkedPullRequest)),
18460
18462
  kind: ThreadKind.pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed("master"))),
@@ -18497,6 +18499,7 @@ const ThreadMetaUpdatedPayload$1 = require_Schema$1.Struct({
18497
18499
  parentThreadId: require_Schema$1.optional(require_Schema$1.NullOr(ThreadId)),
18498
18500
  workerRole: require_Schema$1.optional(require_Schema$1.NullOr(WorkerRole)),
18499
18501
  workSessionId: require_Schema$1.optional(require_Schema$1.NullOr(require_Schema$1.String)),
18502
+ workSessionBoundAt: require_Schema$1.optional(require_Schema$1.String),
18500
18503
  goal: require_Schema$1.optional(require_Schema$1.NullOr(TrimmedNonEmptyString)),
18501
18504
  linkedPullRequest: require_Schema$1.optional(require_Schema$1.NullOr(LinkedPullRequest)),
18502
18505
  regenerateTitle: require_Schema$1.optional(require_Schema$1.Literal(true)),
@@ -66332,7 +66335,7 @@ function normalizeNumberish(value) {
66332
66335
  }
66333
66336
  //#endregion
66334
66337
  //#region package.json
66335
- var version$1 = "0.13.104";
66338
+ var version$1 = "0.13.106";
66336
66339
  //#endregion
66337
66340
  //#region src/sentry.ts
66338
66341
  const SERVER_APP_NAME = "forge-server";
@@ -116049,7 +116052,7 @@ const postgresSchemaStatements = [
116049
116052
  "CREATE TABLE IF NOT EXISTS checkpoint_diff_blobs (\n thread_id TEXT NOT NULL,\n from_turn_count INTEGER NOT NULL,\n to_turn_count INTEGER NOT NULL,\n diff TEXT NOT NULL,\n created_at TEXT NOT NULL,\n UNIQUE (thread_id, from_turn_count, to_turn_count)\n )",
116050
116053
  "CREATE TABLE IF NOT EXISTS provider_session_runtime (\n thread_id TEXT PRIMARY KEY,\n provider_name TEXT NOT NULL,\n adapter_key TEXT NOT NULL,\n runtime_mode TEXT NOT NULL DEFAULT 'full-access',\n status TEXT NOT NULL,\n last_seen_at TEXT NOT NULL,\n resume_cursor_json TEXT,\n runtime_payload_json TEXT\n )",
116051
116054
  "CREATE TABLE IF NOT EXISTS projection_projects (\n project_id TEXT PRIMARY KEY,\n title TEXT NOT NULL,\n workspace_root TEXT NOT NULL,\n scripts_json TEXT NOT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n deleted_at TEXT\n , default_model_selection_json TEXT, default_thread_env_mode TEXT, cmmd_registration_json TEXT)",
116052
- "CREATE TABLE IF NOT EXISTS projection_threads (\n thread_id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL,\n title TEXT NOT NULL,\n branch TEXT,\n worktree_path TEXT,\n latest_turn_id TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n deleted_at TEXT\n , runtime_mode TEXT NOT NULL DEFAULT 'full-access', interaction_mode TEXT NOT NULL DEFAULT 'default', model_selection_json TEXT, archived_at TEXT, latest_user_message_at TEXT, pending_approval_count INTEGER NOT NULL DEFAULT 0, pending_user_input_count INTEGER NOT NULL DEFAULT 0, has_actionable_proposed_plan INTEGER NOT NULL DEFAULT 0, kind TEXT NOT NULL DEFAULT 'master', parent_thread_id TEXT, status TEXT NOT NULL DEFAULT 'idle', anchor_kind TEXT NOT NULL DEFAULT 'scratch', anchor_cmmd_id TEXT, worker_role TEXT DEFAULT NULL, goal TEXT, pending_auto_create_prompt_json TEXT, title_regeneration_json TEXT, rate_limit_status_json TEXT, linked_pull_request_json TEXT, settled_at TEXT, settled_override TEXT, work_session_id TEXT)",
116055
+ "CREATE TABLE IF NOT EXISTS projection_threads (\n thread_id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL,\n title TEXT NOT NULL,\n branch TEXT,\n worktree_path TEXT,\n latest_turn_id TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n deleted_at TEXT\n , runtime_mode TEXT NOT NULL DEFAULT 'full-access', interaction_mode TEXT NOT NULL DEFAULT 'default', model_selection_json TEXT, archived_at TEXT, latest_user_message_at TEXT, pending_approval_count INTEGER NOT NULL DEFAULT 0, pending_user_input_count INTEGER NOT NULL DEFAULT 0, has_actionable_proposed_plan INTEGER NOT NULL DEFAULT 0, kind TEXT NOT NULL DEFAULT 'master', parent_thread_id TEXT, status TEXT NOT NULL DEFAULT 'idle', anchor_kind TEXT NOT NULL DEFAULT 'scratch', anchor_cmmd_id TEXT, worker_role TEXT DEFAULT NULL, goal TEXT, pending_auto_create_prompt_json TEXT, title_regeneration_json TEXT, rate_limit_status_json TEXT, linked_pull_request_json TEXT, settled_at TEXT, settled_override TEXT, work_session_id TEXT, work_session_bound_at TEXT)",
116053
116056
  "CREATE TABLE IF NOT EXISTS projection_thread_messages (\n message_id TEXT PRIMARY KEY,\n thread_id TEXT NOT NULL,\n turn_id TEXT,\n role TEXT NOT NULL,\n text TEXT NOT NULL,\n is_streaming INTEGER NOT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n , attachments_json TEXT)",
116054
116057
  "CREATE TABLE IF NOT EXISTS projection_thread_activities (\n activity_id TEXT PRIMARY KEY,\n thread_id TEXT NOT NULL,\n turn_id TEXT,\n tone TEXT NOT NULL,\n kind TEXT NOT NULL,\n summary TEXT NOT NULL,\n payload_json TEXT NOT NULL,\n created_at TEXT NOT NULL\n , sequence INTEGER)",
116055
116058
  "CREATE TABLE IF NOT EXISTS projection_thread_sessions (\n thread_id TEXT PRIMARY KEY,\n status TEXT NOT NULL,\n provider_name TEXT,\n provider_session_id TEXT,\n provider_thread_id TEXT,\n active_turn_id TEXT,\n last_error TEXT,\n updated_at TEXT NOT NULL\n , runtime_mode TEXT NOT NULL DEFAULT 'full-access')",
@@ -116371,7 +116374,8 @@ const postgresUpgradeMigrations = new Map([
116371
116374
  )
116372
116375
  WHERE model_selection_json IS NULL`
116373
116376
  ]],
116374
- [77, [`ALTER TABLE projection_threads ADD COLUMN IF NOT EXISTS work_session_id TEXT`]]
116377
+ [77, [`ALTER TABLE projection_threads ADD COLUMN IF NOT EXISTS work_session_id TEXT`]],
116378
+ [78, [`ALTER TABLE projection_threads ADD COLUMN IF NOT EXISTS work_session_bound_at TEXT`]]
116375
116379
  ]);
116376
116380
  function requirePostgresUpgradeStatements(version) {
116377
116381
  const statements = postgresUpgradeMigrations.get(version);
@@ -116397,15 +116401,15 @@ const runPostgresMigrations = require_Schema$1.fn("runPostgresMigrations")(funct
116397
116401
  ORDER BY version DESC
116398
116402
  LIMIT 1
116399
116403
  `)[0]?.version ?? 0;
116400
- if (currentVersion > 77) return yield* require_Schema$1.die(/* @__PURE__ */ new Error(`Forge Postgres schema ${currentVersion} is newer than server schema 77.`));
116404
+ if (currentVersion > 78) return yield* require_Schema$1.die(/* @__PURE__ */ new Error(`Forge Postgres schema ${currentVersion} is newer than server schema 78.`));
116401
116405
  if (currentVersion === 0) {
116402
116406
  for (const statement of postgresSchemaStatements) yield* sql.unsafe(statement);
116403
116407
  yield* sql`
116404
116408
  INSERT INTO forge_schema_migrations (version)
116405
- VALUES (${77})
116409
+ VALUES (${78})
116406
116410
  ON CONFLICT (version) DO NOTHING
116407
116411
  `;
116408
- } else for (let version = currentVersion + 1; version <= 77; version += 1) {
116412
+ } else for (let version = currentVersion + 1; version <= 78; version += 1) {
116409
116413
  const statements = yield* require_Schema$1.sync(() => requirePostgresUpgradeStatements(version));
116410
116414
  for (const statement of statements) yield* sql.unsafe(statement);
116411
116415
  yield* sql`
@@ -119202,6 +119206,18 @@ var _077_ProjectionThreadWorkSessionId_default = require_Schema$1.gen(function*
119202
119206
  `;
119203
119207
  });
119204
119208
  //#endregion
119209
+ //#region src/persistence/Migrations/078_ProjectionThreadWorkSessionBoundAt.ts
119210
+ /** Stores the timestamp of the last Work Session binding on a thread (forge#3597). */
119211
+ var _078_ProjectionThreadWorkSessionBoundAt_default = require_Schema$1.gen(function* () {
119212
+ const sql = yield* require_SqlError.SqlClient;
119213
+ if (!(yield* sql`
119214
+ PRAGMA table_info(projection_threads)
119215
+ `).some((column) => column.name === "work_session_bound_at")) yield* sql`
119216
+ ALTER TABLE projection_threads
119217
+ ADD COLUMN work_session_bound_at TEXT
119218
+ `;
119219
+ });
119220
+ //#endregion
119205
119221
  //#region src/persistence/Migrations.ts
119206
119222
  /**
119207
119223
  * MigrationsLive - Migration runner with inline loader
@@ -119607,6 +119623,11 @@ const migrationEntries = [
119607
119623
  77,
119608
119624
  "ProjectionThreadWorkSessionId",
119609
119625
  _077_ProjectionThreadWorkSessionId_default
119626
+ ],
119627
+ [
119628
+ 78,
119629
+ "ProjectionThreadWorkSessionBoundAt",
119630
+ _078_ProjectionThreadWorkSessionBoundAt_default
119610
119631
  ]
119611
119632
  ];
119612
119633
  const makeMigrationLoader = (throughId) => fromRecord(Object.fromEntries(migrationEntries.filter(([id]) => throughId === void 0 || id <= throughId).map(([id, name, migration]) => [`${id}_${name}`, migration])));
@@ -288914,6 +288935,7 @@ const ProjectionThread = require_Schema$1.Struct({
288914
288935
  anchorKind: CmmdAnchorKind.pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed("scratch"))),
288915
288936
  anchorCmmdId: require_Schema$1.NullOr(require_Schema$1.String).pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed(null))),
288916
288937
  workSessionId: require_Schema$1.optionalKey(require_Schema$1.NullOr(require_Schema$1.String)),
288938
+ workSessionBoundAt: require_Schema$1.optionalKey(require_Schema$1.NullOr(require_Schema$1.String)),
288917
288939
  linkedPullRequest: require_Schema$1.optionalKey(require_Schema$1.NullOr(LinkedPullRequest)),
288918
288940
  status: ThreadStatus.pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed("idle"))),
288919
288941
  workerRole: require_Schema$1.NullOr(WorkerRole).pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed(null))),
@@ -293698,6 +293720,15 @@ const make$7 = require_Schema$1.gen(function* () {
293698
293720
  * (FOR-2605).
293699
293721
  */
293700
293722
  const threadSessionAccountIds = /* @__PURE__ */ new Map();
293723
+ /**
293724
+ * The Work Session id each LIVE provider session was started for.
293725
+ *
293726
+ * A Retry creates a new Work Session B on a thread whose session ran for A.
293727
+ * The reactor sees `thread.workSessionId === B` while the session still holds
293728
+ * A's egress credential. Tracking the start-time value lets the reactor
293729
+ * detect the mismatch and restart, dropping A's cached token (forge#3597).
293730
+ */
293731
+ const threadSessionWorkSessionIds = /* @__PURE__ */ new Map();
293701
293732
  const appendProviderFailureActivity = (input) => orchestrationEngine.dispatch({
293702
293733
  type: "thread.activity.append",
293703
293734
  commandId: serverCommandId$2("provider-failure-activity"),
@@ -293766,6 +293797,7 @@ const make$7 = require_Schema$1.gen(function* () {
293766
293797
  runtimeMode: desiredRuntimeMode
293767
293798
  }), () => require_Schema$1.sync(() => {
293768
293799
  threadSessionAccountIds.set(threadId, readProviderAccountId(desiredModelSelection));
293800
+ threadSessionWorkSessionIds.set(threadId, thread.workSessionId ?? null);
293769
293801
  }));
293770
293802
  const bindSessionToThread = (session) => setThreadSession({
293771
293803
  threadId,
@@ -293804,7 +293836,18 @@ const make$7 = require_Schema$1.gen(function* () {
293804
293836
  const desiredAccountId = readProviderAccountId(desiredModelSelection);
293805
293837
  const activeAccountId = threadSessionAccountIds.get(threadId);
293806
293838
  const shouldRestartForAccountChange = threadSessionAccountIds.has(threadId) && activeAccountId !== desiredAccountId;
293807
- if (!runtimeModeChanged && !providerChanged && !shouldRestartForModelChange && !shouldRestartForModelSelectionChange && !shouldRestartForAccountChange) return existingSessionThreadId;
293839
+ /**
293840
+ * A Retry creates a new Work Session B on a thread whose session was
293841
+ * running for A. Once the projector applies the rebind event,
293842
+ * `thread.workSessionId` is B. The session's egress credential was
293843
+ * issued for A and CMMD rejects it with `session_ended` on the first
293844
+ * tool call. Restarting the session drops the cached credential so the
293845
+ * new session mints one bound to B (forge#3597).
293846
+ */
293847
+ const currentWorkSessionId = thread.workSessionId ?? null;
293848
+ const sessionWorkSessionId = threadSessionWorkSessionIds.get(threadId);
293849
+ const shouldRestartForWorkSessionChange = threadSessionWorkSessionIds.has(threadId) && sessionWorkSessionId !== currentWorkSessionId;
293850
+ if (!runtimeModeChanged && !providerChanged && !shouldRestartForModelChange && !shouldRestartForModelSelectionChange && !shouldRestartForAccountChange && !shouldRestartForWorkSessionChange) return existingSessionThreadId;
293808
293851
  const resumeCursor = providerChanged || shouldRestartForModelChange ? void 0 : activeSession?.resumeCursor ?? void 0;
293809
293852
  yield* require_Schema$1.logInfo("provider command reactor restarting provider session", {
293810
293853
  threadId,
@@ -293819,9 +293862,10 @@ const make$7 = require_Schema$1.gen(function* () {
293819
293862
  shouldRestartForModelChange,
293820
293863
  shouldRestartForModelSelectionChange,
293821
293864
  shouldRestartForAccountChange,
293865
+ shouldRestartForWorkSessionChange,
293822
293866
  hasResumeCursor: resumeCursor !== void 0
293823
293867
  });
293824
- if (shouldRestartForAccountChange || providerChanged) yield* providerService.stopSession({
293868
+ if (shouldRestartForAccountChange || shouldRestartForWorkSessionChange || providerChanged) yield* providerService.stopSession({
293825
293869
  threadId,
293826
293870
  preserveResumeState: true
293827
293871
  });
@@ -300297,7 +300341,7 @@ function resolveBuildCommitFromEnv(env) {
300297
300341
  * environment descriptor down instead of reporting an honest "unknown".
300298
300342
  */
300299
300343
  function readBakedBuildCommit() {
300300
- return "e2a39e58fa5d81fe19ff492769b0aba4ddc75c7f";
300344
+ return "1e3b6544bd051026e4c75f595eac2b4c56e720b4";
300301
300345
  }
300302
300346
  async function resolveServerBuildCommit(input) {
300303
300347
  if (isFullCommitSha(input.baked)) return input.baked;
@@ -304164,6 +304208,7 @@ const decideOrchestrationCommand = require_Schema$1.fn("decideOrchestrationComma
304164
304208
  anchorKind: anchor.anchorKind,
304165
304209
  anchorCmmdId: anchor.anchorCmmdId,
304166
304210
  workSessionId: command.workSessionId ?? null,
304211
+ ...command.workSessionId != null ? { workSessionBoundAt: command.createdAt } : {},
304167
304212
  goal: command.goal ?? null,
304168
304213
  linkedPullRequest: command.linkedPullRequest ?? null,
304169
304214
  kind,
@@ -304473,8 +304518,13 @@ const decideOrchestrationCommand = require_Schema$1.fn("decideOrchestrationComma
304473
304518
  const providerSwitchSelection = command.modelSelection !== void 0 && command.modelSelection.provider !== targetThread.modelSelection.provider ? command.modelSelection : void 0;
304474
304519
  const accountSelection = turnAccountSelection(targetThread.modelSelection, command.modelSelection);
304475
304520
  const turnModelSelection = providerSwitchSelection ?? accountSelection;
304521
+ if (command.workSessionId !== void 0 && command.workSessionId !== null && command.workSessionId !== targetThread.workSessionId && targetThread.workSessionBoundAt !== void 0 && targetThread.workSessionBoundAt !== null && command.createdAt <= targetThread.workSessionBoundAt) return yield* new OrchestrationCommandInvariantError({
304522
+ commandType: command.type,
304523
+ detail: `Stale Work Session rebind: kick for session ${String(command.workSessionId)} at ${command.createdAt} is not after workSessionBoundAt ${String(targetThread.workSessionBoundAt)} on thread ${command.threadId}. Thread stays bound to ${String(targetThread.workSessionId)}.`
304524
+ });
304476
304525
  const shouldRebindWorkSession = command.workSessionId !== void 0 && command.workSessionId !== null && command.workSessionId !== targetThread.workSessionId;
304477
- if (!shouldUpdateAnchor && !turnModelSelection && !shouldRebindWorkSession) return [userMessageEvent, turnStartRequestedEvent];
304526
+ const shouldAdvanceBoundTimestamp = !shouldRebindWorkSession && command.workSessionId !== void 0 && command.workSessionId !== null && command.workSessionId === targetThread.workSessionId && (targetThread.workSessionBoundAt === null || targetThread.workSessionBoundAt === void 0 || command.createdAt > targetThread.workSessionBoundAt);
304527
+ if (!shouldUpdateAnchor && !turnModelSelection && !shouldRebindWorkSession && !shouldAdvanceBoundTimestamp) return [userMessageEvent, turnStartRequestedEvent];
304478
304528
  return [
304479
304529
  {
304480
304530
  ...withEventBase({
@@ -304489,7 +304539,10 @@ const decideOrchestrationCommand = require_Schema$1.fn("decideOrchestrationComma
304489
304539
  anchorKind: nextAnchor.anchorKind,
304490
304540
  anchorCmmdId: nextAnchor.anchorCmmdId,
304491
304541
  ...turnModelSelection ? { modelSelection: turnModelSelection } : {},
304492
- ...shouldRebindWorkSession ? { workSessionId: command.workSessionId } : {},
304542
+ ...shouldRebindWorkSession ? {
304543
+ workSessionId: command.workSessionId,
304544
+ workSessionBoundAt: command.createdAt
304545
+ } : shouldAdvanceBoundTimestamp ? { workSessionBoundAt: command.createdAt } : {},
304493
304546
  updatedAt: command.createdAt
304494
304547
  }
304495
304548
  },
@@ -305060,6 +305113,7 @@ function projectEvent(model, event) {
305060
305113
  anchorKind: payload.anchorKind,
305061
305114
  anchorCmmdId: payload.anchorCmmdId,
305062
305115
  workSessionId: payload.workSessionId ?? null,
305116
+ workSessionBoundAt: payload.workSessionBoundAt ?? null,
305063
305117
  goal: payload.goal ?? null,
305064
305118
  linkedPullRequest: payload.linkedPullRequest ?? null,
305065
305119
  titleRegeneration: null,
@@ -305141,6 +305195,7 @@ function projectEvent(model, event) {
305141
305195
  ...payload.linkedPullRequest !== void 0 ? { linkedPullRequest: payload.linkedPullRequest } : {},
305142
305196
  ...payload.titleRegeneration !== void 0 ? { titleRegeneration: payload.titleRegeneration } : {},
305143
305197
  ...payload.workSessionId !== void 0 ? { workSessionId: payload.workSessionId } : {},
305198
+ ...payload.workSessionBoundAt !== void 0 ? { workSessionBoundAt: payload.workSessionBoundAt } : {},
305144
305199
  updatedAt: payload.updatedAt
305145
305200
  })
305146
305201
  })));
@@ -306206,6 +306261,7 @@ const makeProjectionThreadRepository = require_Schema$1.gen(function* () {
306206
306261
  anchor_kind,
306207
306262
  anchor_cmmd_id,
306208
306263
  work_session_id,
306264
+ work_session_bound_at,
306209
306265
  linked_pull_request_json,
306210
306266
  status,
306211
306267
  worker_role,
@@ -306239,6 +306295,7 @@ const makeProjectionThreadRepository = require_Schema$1.gen(function* () {
306239
306295
  ${row.anchorKind},
306240
306296
  ${row.anchorCmmdId},
306241
306297
  ${row.workSessionId ?? null},
306298
+ ${row.workSessionBoundAt ?? null},
306242
306299
  ${row.linkedPullRequest == null ? null : JSON.stringify(row.linkedPullRequest)},
306243
306300
  ${row.status},
306244
306301
  ${row.workerRole},
@@ -306272,6 +306329,7 @@ const makeProjectionThreadRepository = require_Schema$1.gen(function* () {
306272
306329
  anchor_kind = excluded.anchor_kind,
306273
306330
  anchor_cmmd_id = excluded.anchor_cmmd_id,
306274
306331
  work_session_id = excluded.work_session_id,
306332
+ work_session_bound_at = excluded.work_session_bound_at,
306275
306333
  linked_pull_request_json = excluded.linked_pull_request_json,
306276
306334
  status = excluded.status,
306277
306335
  worker_role = excluded.worker_role,
@@ -306310,6 +306368,7 @@ const makeProjectionThreadRepository = require_Schema$1.gen(function* () {
306310
306368
  anchor_kind AS "anchorKind",
306311
306369
  anchor_cmmd_id AS "anchorCmmdId",
306312
306370
  work_session_id AS "workSessionId",
306371
+ work_session_bound_at AS "workSessionBoundAt",
306313
306372
  linked_pull_request_json AS "linkedPullRequest",
306314
306373
  status,
306315
306374
  worker_role AS "workerRole",
@@ -306350,6 +306409,7 @@ const makeProjectionThreadRepository = require_Schema$1.gen(function* () {
306350
306409
  anchor_kind AS "anchorKind",
306351
306410
  anchor_cmmd_id AS "anchorCmmdId",
306352
306411
  work_session_id AS "workSessionId",
306412
+ work_session_bound_at AS "workSessionBoundAt",
306353
306413
  linked_pull_request_json AS "linkedPullRequest",
306354
306414
  status,
306355
306415
  worker_role AS "workerRole",
@@ -306706,6 +306766,7 @@ const makeOrchestrationProjectionPipeline = require_Schema$1.fn("makeOrchestrati
306706
306766
  anchorKind: event.payload.anchorKind,
306707
306767
  anchorCmmdId: event.payload.anchorCmmdId,
306708
306768
  workSessionId: projectedWorkSessionId(event.payload.workSessionId),
306769
+ workSessionBoundAt: event.payload.workSessionBoundAt ?? null,
306709
306770
  linkedPullRequest: event.payload.linkedPullRequest ?? null,
306710
306771
  status: event.payload.status,
306711
306772
  workerRole: event.payload.workerRole,
@@ -306745,6 +306806,7 @@ const makeOrchestrationProjectionPipeline = require_Schema$1.fn("makeOrchestrati
306745
306806
  anchorKind: thread.anchorKind,
306746
306807
  anchorCmmdId: thread.anchorCmmdId,
306747
306808
  workSessionId: projectedWorkSessionId(thread.workSessionId),
306809
+ workSessionBoundAt: thread.workSessionBoundAt ?? null,
306748
306810
  linkedPullRequest: thread.linkedPullRequest ?? null,
306749
306811
  status: thread.status,
306750
306812
  workerRole: thread.workerRole,
@@ -306814,6 +306876,7 @@ const makeOrchestrationProjectionPipeline = require_Schema$1.fn("makeOrchestrati
306814
306876
  ...event.payload.linkedPullRequest !== void 0 ? { linkedPullRequest: event.payload.linkedPullRequest } : {},
306815
306877
  ...event.payload.titleRegeneration !== void 0 ? { titleRegeneration: event.payload.titleRegeneration } : {},
306816
306878
  ...event.payload.workSessionId !== void 0 ? { workSessionId: projectedWorkSessionId(event.payload.workSessionId) } : {},
306879
+ ...event.payload.workSessionBoundAt !== void 0 ? { workSessionBoundAt: event.payload.workSessionBoundAt } : {},
306817
306880
  updatedAt: event.payload.updatedAt
306818
306881
  });
306819
306882
  return;
@@ -307824,6 +307887,13 @@ function toPersistenceSqlOrDecodeError(sqlOperation, decodeOperation) {
307824
307887
  function workSessionIdField(workSessionId) {
307825
307888
  return workSessionId !== void 0 ? { workSessionId } : {};
307826
307889
  }
307890
+ /**
307891
+ * `{ workSessionBoundAt }` when the row carries one, an empty object when absent.
307892
+ * Mirrors `workSessionIdField` so `exactOptionalPropertyTypes` is satisfied. See forge#3611.
307893
+ */
307894
+ function workSessionBoundAtField(workSessionBoundAt) {
307895
+ return workSessionBoundAt !== void 0 ? { workSessionBoundAt } : {};
307896
+ }
307827
307897
  const makeProjectionSnapshotQuery = require_Schema$1.gen(function* () {
307828
307898
  const sql = yield* require_SqlError.SqlClient;
307829
307899
  const repositoryIdentityResolver = yield* RepositoryIdentityResolver;
@@ -307877,6 +307947,7 @@ const makeProjectionSnapshotQuery = require_Schema$1.gen(function* () {
307877
307947
  anchor_kind AS "anchorKind",
307878
307948
  anchor_cmmd_id AS "anchorCmmdId",
307879
307949
  work_session_id AS "workSessionId",
307950
+ work_session_bound_at AS "workSessionBoundAt",
307880
307951
  linked_pull_request_json AS "linkedPullRequest",
307881
307952
  status,
307882
307953
  worker_role AS "workerRole",
@@ -307916,6 +307987,7 @@ const makeProjectionSnapshotQuery = require_Schema$1.gen(function* () {
307916
307987
  anchor_kind AS "anchorKind",
307917
307988
  anchor_cmmd_id AS "anchorCmmdId",
307918
307989
  work_session_id AS "workSessionId",
307990
+ work_session_bound_at AS "workSessionBoundAt",
307919
307991
  linked_pull_request_json AS "linkedPullRequest",
307920
307992
  status,
307921
307993
  worker_role AS "workerRole",
@@ -308021,6 +308093,7 @@ const makeProjectionSnapshotQuery = require_Schema$1.gen(function* () {
308021
308093
  anchor_kind AS "anchorKind",
308022
308094
  anchor_cmmd_id AS "anchorCmmdId",
308023
308095
  work_session_id AS "workSessionId",
308096
+ work_session_bound_at AS "workSessionBoundAt",
308024
308097
  linked_pull_request_json AS "linkedPullRequest",
308025
308098
  status,
308026
308099
  worker_role AS "workerRole",
@@ -308354,6 +308427,7 @@ const makeProjectionSnapshotQuery = require_Schema$1.gen(function* () {
308354
308427
  anchor_kind AS "anchorKind",
308355
308428
  anchor_cmmd_id AS "anchorCmmdId",
308356
308429
  work_session_id AS "workSessionId",
308430
+ work_session_bound_at AS "workSessionBoundAt",
308357
308431
  linked_pull_request_json AS "linkedPullRequest",
308358
308432
  status,
308359
308433
  worker_role AS "workerRole",
@@ -308667,6 +308741,7 @@ const makeProjectionSnapshotQuery = require_Schema$1.gen(function* () {
308667
308741
  anchorKind: row.anchorKind,
308668
308742
  anchorCmmdId: row.anchorCmmdId,
308669
308743
  ...workSessionIdField(row.workSessionId),
308744
+ ...workSessionBoundAtField(row.workSessionBoundAt),
308670
308745
  linkedPullRequest: row.linkedPullRequest,
308671
308746
  kind: row.kind,
308672
308747
  parentThreadId: row.parentThreadId,
@@ -308917,6 +308992,7 @@ const makeProjectionSnapshotQuery = require_Schema$1.gen(function* () {
308917
308992
  anchorKind: threadRow.value.anchorKind,
308918
308993
  anchorCmmdId: threadRow.value.anchorCmmdId,
308919
308994
  ...workSessionIdField(threadRow.value.workSessionId),
308995
+ ...workSessionBoundAtField(threadRow.value.workSessionBoundAt),
308920
308996
  linkedPullRequest: threadRow.value.linkedPullRequest,
308921
308997
  kind: threadRow.value.kind,
308922
308998
  parentThreadId: threadRow.value.parentThreadId,