@quantiya/codevibe-claude-plugin 2.0.74 → 2.0.76

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.
@@ -2799,6 +2799,7 @@ var queries = {
2799
2799
  items {
2800
2800
  eventId
2801
2801
  sessionId
2802
+ sessionGenerationId
2802
2803
  type
2803
2804
  source
2804
2805
  content
@@ -2902,14 +2903,6 @@ var queries = {
2902
2903
  }
2903
2904
  `
2904
2905
  ),
2905
- getGateResolutionV2: (
2906
- /* GraphQL */
2907
- `
2908
- query GetGateResolutionV2($input: GetGateResolutionV2Input!) {
2909
- getGateResolutionV2(input: $input)
2910
- }
2911
- `
2912
- ),
2913
2906
  getGateResolution: (
2914
2907
  /* GraphQL */
2915
2908
  `
@@ -3253,27 +3246,17 @@ var queries = {
3253
3246
  }
3254
3247
  `
3255
3248
  ),
3256
- createEventV2: (
3257
- /* GraphQL */
3258
- `
3259
- mutation CreateEventV2($input: CreateEventV2Input!) {
3260
- createEventV2(input: $input)
3261
- }
3262
- `
3263
- ),
3264
- recordWorkspaceOutcomeV2: (
3249
+ updateEvent: (
3265
3250
  /* GraphQL */
3266
3251
  `
3267
- mutation RecordWorkspaceOutcomeV2($input: AWSJSON!) {
3268
- recordWorkspaceOutcomeV2(input: $input)
3269
- }
3270
- `
3271
- ),
3272
- updateEventV2: (
3273
- /* GraphQL */
3274
- `
3275
- mutation UpdateEventV2($input: UpdateEventV2Input!) {
3276
- updateEventV2(input: $input)
3252
+ mutation UpdateEvent($input: UpdateEventInput!) {
3253
+ updateEvent(input: $input) {
3254
+ eventId sessionId sessionGenerationId type source timestamp emittedBy
3255
+ content metadata promptId deliveryStatus deliveredAt executedAt
3256
+ attachments { id type filename s3Key size width height }
3257
+ isEncrypted encryptionVersion writerAuthenticated writerEventNonce
3258
+ writerEventKind writerSessionGenerationId
3259
+ }
3277
3260
  }
3278
3261
  `
3279
3262
  ),
@@ -3317,35 +3300,19 @@ var queries = {
3317
3300
  }
3318
3301
  `
3319
3302
  ),
3320
- refreshOpenPromptTtlV2: (
3321
- /* GraphQL */
3322
- `
3323
- mutation RefreshOpenPromptTtlV2($promptId: ID!) {
3324
- refreshOpenPromptTtlV2(promptId: $promptId)
3325
- }
3326
- `
3327
- ),
3328
- resolveOpenPromptV2: (
3303
+ reportSecurityPosture: (
3329
3304
  /* GraphQL */
3330
3305
  `
3331
- mutation ResolveOpenPromptV2($input: ResolveOpenPromptV2Input!) {
3332
- resolveOpenPromptV2(input: $input)
3306
+ mutation ReportSecurityPosture($input: AWSJSON!) {
3307
+ reportSecurityPosture(input: $input)
3333
3308
  }
3334
3309
  `
3335
3310
  ),
3336
- reportSecurityPostureV2: (
3311
+ confirmSessionRetirement: (
3337
3312
  /* GraphQL */
3338
3313
  `
3339
- mutation ReportSecurityPostureV2($input: AWSJSON!) {
3340
- reportSecurityPostureV2(input: $input)
3341
- }
3342
- `
3343
- ),
3344
- confirmSessionRetirementV2: (
3345
- /* GraphQL */
3346
- `
3347
- mutation ConfirmSessionRetirementV2($input: ConfirmSessionRetirementV2Input!) {
3348
- confirmSessionRetirementV2(input: $input)
3314
+ mutation ConfirmSessionRetirement($input: ConfirmSessionRetirementInput!) {
3315
+ confirmSessionRetirement(input: $input)
3349
3316
  }
3350
3317
  `
3351
3318
  ),
@@ -3356,6 +3323,7 @@ var queries = {
3356
3323
  updateEventStatus(input: $input) {
3357
3324
  eventId
3358
3325
  sessionId
3326
+ sessionGenerationId
3359
3327
  type
3360
3328
  source
3361
3329
  content
@@ -3369,14 +3337,6 @@ var queries = {
3369
3337
  }
3370
3338
  `
3371
3339
  ),
3372
- updateEventStatusV2: (
3373
- /* GraphQL */
3374
- `
3375
- mutation UpdateEventStatusV2($input: UpdateEventStatusV2Input!) {
3376
- updateEventStatusV2(input: $input)
3377
- }
3378
- `
3379
- ),
3380
3340
  registerDeviceKey: (
3381
3341
  /* GraphQL */
3382
3342
  `
@@ -3591,11 +3551,11 @@ var queries = {
3591
3551
  }
3592
3552
  `
3593
3553
  ),
3594
- submitGateDecisionV2: (
3554
+ submitGateDecision: (
3595
3555
  /* GraphQL */
3596
3556
  `
3597
- mutation SubmitGateDecisionV2($input: SubmitGateDecisionV2Input!) {
3598
- submitGateDecisionV2(input: $input) {
3557
+ mutation SubmitGateDecision($input: SubmitGateDecisionInput!) {
3558
+ submitGateDecision(input: $input) {
3599
3559
  decisionAttemptId
3600
3560
  acceptanceStatus
3601
3561
  decisionClaimId
@@ -3610,11 +3570,11 @@ var queries = {
3610
3570
  }
3611
3571
  `
3612
3572
  ),
3613
- submitGroupDecisionV2: (
3573
+ submitGroupDecision: (
3614
3574
  /* GraphQL */
3615
3575
  `
3616
- mutation SubmitGroupDecisionV2($input: SubmitGroupDecisionV2Input!) {
3617
- submitGroupDecisionV2(input: $input) {
3576
+ mutation SubmitGroupDecision($input: SubmitGroupDecisionInput!) {
3577
+ submitGroupDecision(input: $input) {
3618
3578
  decisionAttemptId
3619
3579
  acceptanceStatus
3620
3580
  decisionClaimId
@@ -3707,11 +3667,11 @@ var queries = {
3707
3667
  }
3708
3668
  `
3709
3669
  ),
3710
- commitGroupDecisionV2: (
3670
+ commitGroupDecision: (
3711
3671
  /* GraphQL */
3712
3672
  `
3713
- mutation CommitGroupDecisionV2($input: CommitGroupDecisionV2Input!) {
3714
- commitGroupDecisionV2(input: $input) {
3673
+ mutation CommitGroupDecision($input: CommitGroupDecisionInput!) {
3674
+ commitGroupDecision(input: $input) {
3715
3675
  taskGroupId decisionClaimId commitStatus workflowStatus groupStatus committedAt
3716
3676
  }
3717
3677
  }
@@ -3893,6 +3853,9 @@ var queries = {
3893
3853
  onEventCreated(sessionId: $sessionId) {
3894
3854
  eventId
3895
3855
  sessionId
3856
+ sessionGenerationId
3857
+ syncEventRevision
3858
+ syncImmutableIdentityDigest
3896
3859
  type
3897
3860
  source
3898
3861
  content
@@ -4151,22 +4114,6 @@ function signDesktopSyncInput(action, data, userId, keys, issuedAtEpochMs) {
4151
4114
  desktopProof: Object.freeze({ ...proof, signature })
4152
4115
  });
4153
4116
  }
4154
- function parseSyncEventMutationResponse(value, expected) {
4155
- let bad3 = () => {
4156
- throw new SyncEventClientError("INVALID_SYNC_RECEIPT");
4157
- };
4158
- if (typeof value == "string") {
4159
- Buffer.byteLength(value) > 2048 && bad3();
4160
- try {
4161
- value = JSON.parse(value);
4162
- } catch {
4163
- bad3();
4164
- }
4165
- }
4166
- plain(value) || bad3();
4167
- let row3 = value, refreshSyncState = own(row3, "refreshSyncState");
4168
- return refreshSyncState && row3.refreshSyncState !== !0 && bad3(), { receipt: parseSyncEventReceipt(Object.fromEntries(Object.entries(row3).filter(([field2]) => field2 !== "refreshSyncState")), expected), refreshSyncState };
4169
- }
4170
4117
  function parseSyncEventReceipt(value, expected) {
4171
4118
  let bad3 = () => {
4172
4119
  throw new SyncEventClientError("INVALID_SYNC_RECEIPT");
@@ -4213,8 +4160,8 @@ function parseSyncPromptRetentionReceipt(value, promptId2) {
4213
4160
  }
4214
4161
  }
4215
4162
  plain(value) || bad3();
4216
- let row3 = value, keys = row3.status === "REFRESHED" ? ["expiresAt", "promptId", "status"] : ["promptId", "status"];
4217
- return (Object.keys(row3).sort().join(",") !== keys.join(",") || row3.promptId !== promptId2 || !ID.test(promptId2) || !["REFRESHED", "RERAISE_REQUIRED"].includes(row3.status) || row3.status === "REFRESHED" && (typeof row3.expiresAt != "number" || !Number.isSafeInteger(row3.expiresAt) || row3.expiresAt <= 0 || row3.expiresAt > 253402300799)) && bad3(), Object.freeze({ ...row3 });
4163
+ let row3 = value, keys = row3.status === "REFRESHED" && own(row3, "expiresAt") ? ["expiresAt", "promptId", "status"] : ["promptId", "status"];
4164
+ return (Object.keys(row3).sort().join(",") !== keys.join(",") || row3.promptId !== promptId2 || !ID.test(promptId2) || !["REFRESHED", "RERAISE_REQUIRED"].includes(row3.status) || row3.status === "REFRESHED" && own(row3, "expiresAt") && (typeof row3.expiresAt != "number" || !Number.isSafeInteger(row3.expiresAt) || row3.expiresAt <= 0 || row3.expiresAt > 253402300799)) && bad3(), Object.freeze({ ...row3 });
4218
4165
  }
4219
4166
 
4220
4167
  // src/appsync/sync-state.ts
@@ -4291,7 +4238,7 @@ function parseCompanionSyncState(value, environment, now = Date.now()) {
4291
4238
  let committed = count(value.usage[`${meter}Committed`]);
4292
4239
  count(value.usage[`${meter}Reserved`]);
4293
4240
  let limit = count(value.usage[`${meter}Limit`]), pausedAtLimit = count(value.usage[`${meter}PauseLimit`]);
4294
- pausedAtLimit > 0n && gap2 === 0n && invalid2(), value.usage[`${meter}Limit`] !== value.limits[meter] && invalid2(), committed >= limit || pausedAtLimit >= limit ? state = "PAUSED" : committed * 5n >= limit * 4n && state !== "PAUSED" && (state = "WARNING");
4241
+ pausedAtLimit > 0n && gap2 === 0n && invalid2(), value.usage[`${meter}Limit`] !== value.limits[meter] && invalid2(), meter === "syncUnits" && (committed >= limit || pausedAtLimit >= limit) ? state = "PAUSED" : committed * 5n >= limit * 4n && state !== "PAUSED" && (state = "WARNING");
4295
4242
  }
4296
4243
  value.usage.syncState !== state && invalid2();
4297
4244
  } else (value.protocol === "SYNC_V2" && value.mode !== "SHADOW" || value.mode === "ROLLBACK_FREEZE" && value.protocol !== "FROZEN" || value.usage !== null || value.periodId !== null || value.resetAtEpochMs !== null) && invalid2();
@@ -4389,7 +4336,7 @@ function parseWorkspaceOutcomeReceipt(value, expected) {
4389
4336
  }
4390
4337
  return !exact(value, RECEIPT2) || Buffer.byteLength(JSON.stringify(value)) > 2048 || value.schemaVersion !== 1 || value.kind !== "WORKSPACE_OUTCOME" || value.state !== "ACKED" || value.sessionId !== expected.sessionId || value.sessionGenerationId !== expected.writerSessionGenerationId || value.writerEventNonce !== expected.writerAttestation?.writerEventNonce || typeof value.eventId != "string" || !UUID3.test(value.eventId) || typeof value.timestamp != "string" || !Number.isFinite(Date.parse(value.timestamp)) || new Date(value.timestamp).toISOString() !== value.timestamp || !["ADMITTED", "OMITTED_QUOTA", "LEGACY_COMMITTED"].includes(value.syncDisposition) ? bad("INVALID_SYNC_RECEIPT") : Object.freeze({ ...value });
4391
4338
  }
4392
- function legacyWorkspaceOutcomeReceipt(event, expected) {
4339
+ function workspaceOutcomeEventReceipt(event, expected) {
4393
4340
  return !event || event.sessionId !== expected.sessionId || event.type !== "NOTIFICATION" || event.source !== "DESKTOP" || event.writerAuthenticated !== !0 || event.writerEventKind !== "WORKSPACE_OUTCOME" || event.writerEventNonce !== expected.writerAttestation?.writerEventNonce || event.writerSessionGenerationId !== expected.writerSessionGenerationId ? bad("INVALID_SYNC_RECEIPT") : parseWorkspaceOutcomeReceipt({
4394
4341
  schemaVersion: 1,
4395
4342
  kind: "WORKSPACE_OUTCOME",
@@ -4399,7 +4346,7 @@ function legacyWorkspaceOutcomeReceipt(event, expected) {
4399
4346
  writerEventNonce: event.writerEventNonce,
4400
4347
  eventId: event.eventId,
4401
4348
  timestamp: event.timestamp,
4402
- syncDisposition: "LEGACY_COMMITTED"
4349
+ syncDisposition: "ADMITTED"
4403
4350
  }, expected);
4404
4351
  }
4405
4352
 
@@ -7327,6 +7274,7 @@ function createDesktopInbound(options) {
7327
7274
  uncertain: row3.entries.filter((e) => e.state === "UNCERTAIN" && !e.localExecuted).length
7328
7275
  };
7329
7276
  })),
7277
+ retainedCoordinates: () => options.locked(async () => Object.freeze((await read()).entries.map((e) => Object.freeze({ ...e.target })))),
7330
7278
  pendingAcknowledgements: () => options.locked(async () => {
7331
7279
  let row3 = await read();
7332
7280
  return Object.freeze(row3.entries.filter((e) => e.state === "HANDED_OFF" || e.state === "UNCERTAIN").map((e) => Object.freeze({ ...e.target })));
@@ -7555,12 +7503,12 @@ function decodePromptRetention(value) {
7555
7503
  return row3;
7556
7504
  }
7557
7505
  function createPromptRetentionJournal(store) {
7558
- return Object.freeze({ run: (values, refresh, reRaise, now = Date.now) => {
7506
+ return Object.freeze({ run: (values, refresh, reRaise) => {
7559
7507
  let promptIds = [...new Set(import_zod7.z.array(id4).max(4096).parse(values))].sort();
7560
7508
  return store.runExclusive(async (fence) => {
7561
- let row3 = await store.read(), live = new Set(promptIds), save = async () => {
7509
+ let row3 = await store.read(), save = async () => {
7562
7510
  await fence(), await store.write(decodePromptRetention(row3)), await fence();
7563
- }, retained = row3.entries.filter((e) => live.has(e.promptId) || e.status === "RERAISE_REQUIRED");
7511
+ }, retained = row3.entries.filter((e) => e.status === "RERAISE_REQUIRED");
7564
7512
  retained.length !== row3.entries.length && (row3.entries = retained, await save());
7565
7513
  let settle = async (promptId2) => {
7566
7514
  await fence();
@@ -7572,8 +7520,7 @@ function createPromptRetentionJournal(store) {
7572
7520
  row3.entries = row3.entries.filter((e) => e.promptId !== promptId2), await save();
7573
7521
  }, split = row3.cursor === null ? 0 : promptIds.findIndex((promptId2) => promptId2 > row3.cursor), start = split < 0 ? 0 : split, ordered = [...promptIds.slice(start), ...promptIds.slice(0, start)];
7574
7522
  for (let promptId2 of ordered) {
7575
- let at = time4.parse(now()), prior = row3.entries.find((e) => e.promptId === promptId2);
7576
- if (prior?.status === "REFRESHED" && at >= prior.checkedAt && at < prior.checkAfter) continue;
7523
+ let prior = row3.entries.find((e) => e.promptId === promptId2);
7577
7524
  if (!prior && row3.entries.length >= 4096) throw Error("SYNC_JOURNAL_FULL");
7578
7525
  if (row3.cursor = promptId2, await save(), prior?.status === "RERAISE_REQUIRED") {
7579
7526
  await settle(promptId2);
@@ -7581,13 +7528,7 @@ function createPromptRetentionJournal(store) {
7581
7528
  }
7582
7529
  await fence();
7583
7530
  let receipt2 = parseSyncPromptRetentionReceipt(await refresh(promptId2), promptId2);
7584
- await fence();
7585
- let checkedAt = time4.parse(now()), next = receipt2.status === "RERAISE_REQUIRED" ? { ...receipt2, reRaiseToken: (0, import_node_crypto11.randomUUID)() } : {
7586
- ...receipt2,
7587
- checkedAt,
7588
- checkAfter: Math.max(checkedAt, Math.min(checkedAt + 864e5, receipt2.expiresAt * 1e3 - 864e5))
7589
- };
7590
- row3.entries = row3.entries.filter((e) => e.promptId !== promptId2), row3.entries.push(next), await save(), receipt2.status === "RERAISE_REQUIRED" && await settle(promptId2);
7531
+ await fence(), receipt2.status === "RERAISE_REQUIRED" && (row3.entries.push({ ...receipt2, reRaiseToken: (0, import_node_crypto11.randomUUID)() }), await save(), await settle(promptId2));
7591
7532
  }
7592
7533
  });
7593
7534
  }, remove: () => store.runExclusive(async (fence) => {
@@ -7985,7 +7926,7 @@ var sourceCursorId = (scope, stream) => stableUuid("codevibe-sync-source-cursor-
7985
7926
  });
7986
7927
  }
7987
7928
  async shellSources() {
7988
- return this.withStore(async (key) => {
7929
+ return this.options.assertAccount(), await this.ensureDirectory(), (await this.recordNames(".shell")).length ? this.withStore(async (key) => {
7989
7930
  let result = [];
7990
7931
  for (let name of await this.recordNames(".shell")) {
7991
7932
  let id5 = name.slice(0, -6), row3 = await this.readShellSource(id5, key);
@@ -7998,7 +7939,7 @@ var sourceCursorId = (scope, stream) => stableUuid("codevibe-sync-source-cursor-
7998
7939
  });
7999
7940
  }
8000
7941
  return result.sort((a, b) => a.sourceId.localeCompare(b.sourceId));
8001
- });
7942
+ }) : (this.options.assertAccount(), []);
8002
7943
  }
8003
7944
  /** One encrypted intent/credential record per original desktop incarnation.
8004
7945
  * This uses the account journal's existing 256-file / 32-MiB total bound. */
@@ -8272,7 +8213,7 @@ var sourceCursorId = (scope, stream) => stableUuid("codevibe-sync-source-cursor-
8272
8213
  if (errorCode(error) !== "ENOENT") throw error;
8273
8214
  return this.options.assertAccount(), [];
8274
8215
  }
8275
- return this.withStore(async (key) => {
8216
+ return await this.ensureDirectory(), (await this.recordNames(".prompt")).length ? this.withStore(async (key) => {
8276
8217
  let results = [];
8277
8218
  for (let name of await this.recordNames(".prompt")) {
8278
8219
  let id5 = name.slice(0, -7), row3 = await this.readValue(id5, key, ".prompt", (value) => decodePromptPublication(value, invalid7));
@@ -8288,6 +8229,34 @@ var sourceCursorId = (scope, stream) => stableUuid("codevibe-sync-source-cursor-
8288
8229
  });
8289
8230
  }
8290
8231
  return results;
8232
+ }) : (this.options.assertAccount(), []);
8233
+ }
8234
+ /** Metadata-only inventory for preserving pre-consolidation re-raise owners.
8235
+ * These generations identify local receipts, never a cloud API or tier. */
8236
+ async promptRetentionScopes() {
8237
+ this.options.assertAccount();
8238
+ try {
8239
+ await import_node_fs2.promises.lstat(this.directory);
8240
+ } catch (error) {
8241
+ if (errorCode(error) !== "ENOENT") throw error;
8242
+ return this.options.assertAccount(), [];
8243
+ }
8244
+ return this.withStore(async (key) => {
8245
+ let scopes = [];
8246
+ for (let name of await this.recordNames(".retention")) {
8247
+ let id5 = name.slice(0, -10), row3 = await this.readValue(id5, key, ".retention", decodePromptRetention);
8248
+ if (!row3 || row3.operationId !== id5 || id5 !== stableUuid(
8249
+ "codevibe-sync-prompt-retention-v1\0",
8250
+ [row3.sessionId, row3.sessionGenerationId]
8251
+ )) return invalid7();
8252
+ let promptIds = row3.entries.filter((entry5) => entry5.status === "RERAISE_REQUIRED").map((entry5) => entry5.promptId);
8253
+ this.matchesScope(row3) && promptIds.length && scopes.push({
8254
+ sessionId: row3.sessionId,
8255
+ sessionGenerationId: row3.sessionGenerationId,
8256
+ promptIds
8257
+ });
8258
+ }
8259
+ return scopes;
8291
8260
  });
8292
8261
  }
8293
8262
  promptRetention() {
@@ -8428,10 +8397,19 @@ var sourceCursorId = (scope, stream) => stableUuid("codevibe-sync-source-cursor-
8428
8397
  scope,
8429
8398
  locked: (fn) => locked(`inbound-record-${id5}.lockdir`, fn),
8430
8399
  dispatchLocked: (fn) => locked(`inbound-dispatch-${id5}.lockdir`, fn),
8431
- read: () => this.withStore((key) => this.readValue(id5, key, ".inbox", (value) => {
8432
- let row3 = decodeDesktopInbound(value);
8433
- return row3.operationId !== id5 ? invalid7() : (this.requireScope(row3), row3);
8434
- })),
8400
+ read: async () => {
8401
+ this.options.assertAccount();
8402
+ try {
8403
+ await import_node_fs2.promises.lstat(this.file(id5, ".inbox"));
8404
+ } catch (error) {
8405
+ if (errorCode(error) === "ENOENT") return null;
8406
+ throw error;
8407
+ }
8408
+ return this.withStore((key) => this.readValue(id5, key, ".inbox", (value) => {
8409
+ let row3 = decodeDesktopInbound(value);
8410
+ return row3.operationId !== id5 ? invalid7() : (this.requireScope(row3), row3);
8411
+ }));
8412
+ },
8435
8413
  write: (row3) => this.withStore(async (key) => {
8436
8414
  let sealed = this.seal(row3, key);
8437
8415
  await this.checkCapacity(Buffer.byteLength(sealed), id5 + ".inbox"), await this.write(id5, sealed, ".inbox");
@@ -9077,6 +9055,31 @@ var count3 = import_zod9.z.string().regex(/^(0|[1-9][0-9]{0,18})$/).refine((s) =
9077
9055
  sameScope(value) {
9078
9056
  return value.sessionId === this.scope.sessionId && value.sessionGenerationId === this.scope.sessionGenerationId;
9079
9057
  }
9058
+ /** One finite upgrade recovery pass, not a live delivery transport. Recover
9059
+ * saved coordinates and previously accepted lifecycle inputs whose hints
9060
+ * never reached this host. Ordinary canonical Events have no lifecycle stamp
9061
+ * and are left to AppSync. No socket, history scan, maintenance or timer. */
9062
+ recoverAcceptedInputs(onCoordinate) {
9063
+ return this.starting || this.phase !== "new" ? Promise.reject(failure()) : (this.phase = "ready", this.starting = Promise.resolve().then(async () => {
9064
+ this.fence();
9065
+ let recovery = await this.deps.inbound.recoverable();
9066
+ this.fence();
9067
+ for (let target2 of await this.deps.inbound.pendingAcknowledgements())
9068
+ await this.reconcileAcknowledgement(target2);
9069
+ for (let target2 of recovery.pending)
9070
+ this.fence(), await this.reconcileReceived(await this.deps.reader.recoverCurrent(target2, this.abort.signal), target2);
9071
+ let cursor;
9072
+ do {
9073
+ let page = await this.deps.reader.pendingInputs(cursor, this.abort.signal);
9074
+ this.fence();
9075
+ for (let coordinate2 of page.items)
9076
+ await this.discoverCoordinate(coordinate2, { retainedLifecycleOnly: !0, onCoordinate });
9077
+ cursor = page.nextToken ?? void 0;
9078
+ } while (cursor);
9079
+ let remaining = await this.deps.inbound.recoverable();
9080
+ this.fence(), remaining.uncertain && this.deps.onUncertain?.(remaining.uncertain);
9081
+ }), this.starting);
9082
+ }
9080
9083
  start() {
9081
9084
  if (this.starting) return this.starting;
9082
9085
  if (this.phase !== "new") return Promise.reject(failure());
@@ -9301,11 +9304,15 @@ var count3 = import_zod9.z.string().regex(/^(0|[1-9][0-9]{0,18})$/).refine((s) =
9301
9304
  this.fence(), status.uncertain && this.deps.onUncertain?.(status.uncertain), this.recoveryPages = 0, this.scheduleDiscovery(PING);
9302
9305
  }
9303
9306
  }
9304
- async discoverCoordinate(coordinate2) {
9307
+ async discoverCoordinate(coordinate2, upgrade) {
9305
9308
  let retained = await this.deps.inbound.pendingAcknowledgements();
9306
9309
  if (this.fence(), retained.some((item2) => item2.eventId === coordinate2.eventId && item2.timestamp === coordinate2.timestamp)) return;
9307
9310
  let event = await this.deps.reader.pendingInput(coordinate2, this.abort.signal);
9308
- this.fence(), event && (event.deliveryStatus === "EXECUTED" ? await this.deps.inbound.acknowledgeExecuted({ ...event, deliveryStatus: "EXECUTED" }) : await this.deps.inbound.stageDiscovered(event) === "RECEIVED" && await this.deliver(event, { timestamp: event.timestamp, eventRevision: event.syncEventRevision }));
9311
+ if (this.fence(), !event) {
9312
+ if (upgrade) throw new SyncReadClientError("SYNC_READ_UNAVAILABLE", "EVENT_FETCH_UNAVAILABLE");
9313
+ return;
9314
+ }
9315
+ upgrade && (event.syncLifecycleVersion !== 1 || event.syncLegacyProjection === 1) || (upgrade?.onCoordinate?.(coordinate2), event.deliveryStatus === "EXECUTED" ? await this.deps.inbound.acknowledgeExecuted({ ...event, deliveryStatus: "EXECUTED" }) : await this.deps.inbound.stageDiscovered(event) === "RECEIVED" && await this.deliver(event, { timestamp: event.timestamp, eventRevision: event.syncEventRevision }));
9309
9316
  }
9310
9317
  startPings() {
9311
9318
  this.pingTimer = setInterval(() => {
@@ -10968,11 +10975,11 @@ function parseGroupOperationResult(raw, operation) {
10968
10975
  }
10969
10976
  function parseGroupDecisionCommitResult(raw) {
10970
10977
  if (!raw || typeof raw != "object" || Array.isArray(raw))
10971
- throw new Error("commitGroupDecisionV2: malformed result");
10978
+ throw new Error("commitGroupDecision: malformed result");
10972
10979
  let value = raw;
10973
- if (typeof value.taskGroupId != "string" || typeof value.decisionClaimId != "string" || !["COMMITTED", "ALREADY_COMMITTED", "PENDING_RECOVERY"].includes(String(value.commitStatus)) || !["COMPLETE", "PENDING_ERROR"].includes(String(value.workflowStatus))) throw new Error("commitGroupDecisionV2: malformed identity or status");
10980
+ if (typeof value.taskGroupId != "string" || typeof value.decisionClaimId != "string" || !["COMMITTED", "ALREADY_COMMITTED", "PENDING_RECOVERY"].includes(String(value.commitStatus)) || !["COMPLETE", "PENDING_ERROR"].includes(String(value.workflowStatus))) throw new Error("commitGroupDecision: malformed identity or status");
10974
10981
  let pending = value.commitStatus === "PENDING_RECOVERY";
10975
- if (pending !== (value.workflowStatus === "PENDING_ERROR") || pending && (value.groupStatus !== null || value.committedAt !== null) || !pending && (!["COMPLETE", "HALTED"].includes(String(value.groupStatus)) || typeof value.committedAt != "string" || !Number.isFinite(Date.parse(value.committedAt)))) throw new Error("commitGroupDecisionV2: contradictory result state");
10982
+ if (pending !== (value.workflowStatus === "PENDING_ERROR") || pending && (value.groupStatus !== null || value.committedAt !== null) || !pending && (!["COMPLETE", "HALTED"].includes(String(value.groupStatus)) || typeof value.committedAt != "string" || !Number.isFinite(Date.parse(value.committedAt)))) throw new Error("commitGroupDecision: contradictory result state");
10976
10983
  return value;
10977
10984
  }
10978
10985
  function optionalCount(source2, key) {
@@ -11613,14 +11620,11 @@ var AppSyncClient = class _AppSyncClient {
11613
11620
  throw [
11614
11621
  mutations.createEvent,
11615
11622
  mutations.updateEventStatus,
11616
- mutations.createEventV2,
11617
- mutations.updateEventV2,
11618
- mutations.recordWorkspaceOutcomeV2,
11619
- mutations.reportSecurityPostureV2,
11623
+ mutations.updateEvent,
11624
+ mutations.reportSecurityPosture,
11620
11625
  queries.listEvents,
11621
11626
  queries.listSupervisionEvents,
11622
- queries.getGateResolution,
11623
- queries.getGateResolutionV2
11627
+ queries.getGateResolution
11624
11628
  ].includes(query) && syncUserId === this.currentUserId && syncEpoch === this.syncDisplayEpoch && ["UPDATE_REQUIRED", "AUTHORITY_UNAVAILABLE", "SYNC_BLOCKED"].includes(first.errorType ?? "") && this.resetCompanionSyncDisplay(), new AppSyncGraphQLError({
11625
11629
  message: first.message,
11626
11630
  errorType: first.errorType,
@@ -11738,19 +11742,6 @@ var AppSyncClient = class _AppSyncClient {
11738
11742
  throw this.publishCompanionSyncDisplay(userId, null, epoch, sequence), error;
11739
11743
  }
11740
11744
  }
11741
- /** Reuse only the server-unexpired protocol selection, never its entitlement
11742
- * or usage as admission authority. Every selected cloud operation still
11743
- * authorizes itself. Explicit status/quota refreshes remain fresh reads. */
11744
- async getCompanionSyncRoute(signal) {
11745
- let userId = this.getCurrentUserId(), epoch = this.syncDisplayEpoch, check = () => {
11746
- if (this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal), epoch !== this.syncDisplayEpoch) throw new SyncEventClientError("INVALID_SYNC_STATE");
11747
- };
11748
- check();
11749
- let cached = this.companionSyncStatusSnapshot(userId);
11750
- if (cached) return { protocol: cached.protocol };
11751
- let state = await this.getCompanionSyncState(signal);
11752
- return check(), { protocol: state.protocol };
11753
- }
11754
11745
  /** Subscribe to validated reads already performed by this client. No new
11755
11746
  * request, persistent journal, producer grant or retry is created here. */
11756
11747
  subscribeCompanionSyncState(userId, listener) {
@@ -11800,8 +11791,8 @@ var AppSyncClient = class _AppSyncClient {
11800
11791
  for (let entry5 of this.syncDisplayListeners) this.notifyCompanionSyncDisplay(entry5);
11801
11792
  return state;
11802
11793
  }
11803
- /** Signed closed safety fact, independent of customer event quota. Only an
11804
- * affirmative cloud LEGACY selection permits the caller's legacy sink.
11794
+ /** Signed closed safety fact. The cloud owns availability/accounting policy;
11795
+ * no client status read or transport selection precedes this operation.
11805
11796
  * Success confirms canonical persistence, never phone/render delivery. */
11806
11797
  async reportSecurityPostureIfSelected(sessionScope, posture, signal) {
11807
11798
  let scope = {
@@ -11810,11 +11801,7 @@ var AppSyncClient = class _AppSyncClient {
11810
11801
  expectedSessionKeyGen: sessionScope.sessionKeyGen ?? SESSION_KEY_GEN_ABSENT_SENTINEL,
11811
11802
  posture
11812
11803
  }, userId = this.getCurrentUserId();
11813
- this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal);
11814
- let state = await this.getCompanionSyncRoute(signal);
11815
- if (this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal), state.protocol === "LEGACY") return null;
11816
- if (state.protocol !== "SYNC_V2") throw new SyncEventClientError("SYNC_PRODUCER_FROZEN");
11817
- if (!scope.sessionGenerationId) throw new SyncEventClientError("SYNC_SESSION_GENERATION_CHANGED");
11804
+ if (this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal), !scope.sessionGenerationId) throw new SyncEventClientError("SYNC_SESSION_GENERATION_CHANGED");
11818
11805
  let input = makeSyncSecurityPostureInput(userId, { ...scope, sessionGenerationId: scope.sessionGenerationId }), identity = await keychainManager.getDeviceIdentity();
11819
11806
  if (this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal), !identity) throw new SyncEventClientError("SYNC_IDENTITY_UNAVAILABLE");
11820
11807
  if (this.tokens && this.tokens.expiresAt <= Date.now() && await this.refreshTokens(this.tokens, signal), this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal), getConfig().environment !== this.environment) throw new SyncEventClientError("SYNC_SESSION_UNAVAILABLE");
@@ -11825,22 +11812,20 @@ var AppSyncClient = class _AppSyncClient {
11825
11812
  { privateKeyB64: identity.privateKey, publicKeyB64: identity.publicKey },
11826
11813
  Date.now()
11827
11814
  ), response = await this.graphqlRequest(
11828
- mutations.reportSecurityPostureV2,
11815
+ mutations.reportSecurityPosture,
11829
11816
  { input: JSON.stringify(signed) },
11830
11817
  !0,
11831
11818
  signal,
11832
11819
  userId,
11833
11820
  8192
11834
11821
  );
11835
- return this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal), parseSyncSecurityPostureReceipt(response?.data?.reportSecurityPostureV2, input);
11822
+ return this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal), parseSyncSecurityPostureReceipt(response?.data?.reportSecurityPosture, input);
11836
11823
  }
11837
11824
  /** Explicit bounded read plane. No registration, paging or legacy fallback
11838
11825
  * occurs at construction; lifecycle owners persist and supply credentials. */
11839
11826
  async desktopSyncReadClient(sessionScope, signal) {
11840
11827
  let scope = { ...sessionScope }, userId = this.getCurrentUserId();
11841
11828
  this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal);
11842
- let state = await this.getCompanionSyncRoute(signal);
11843
- if (this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal), state.protocol !== "SYNC_V2") throw new SyncEventClientError("SYNC_PRODUCER_FROZEN");
11844
11829
  let config = getConfig();
11845
11830
  if (config.environment !== this.environment || !config.aws.syncHttpUrl) throw new SyncEventClientError("SYNC_SESSION_UNAVAILABLE");
11846
11831
  return new DesktopSyncReadClient({
@@ -11853,15 +11838,8 @@ var AppSyncClient = class _AppSyncClient {
11853
11838
  if (this.assertSyncAccount(userId), !identity) throw new SyncEventClientError("SYNC_IDENTITY_UNAVAILABLE");
11854
11839
  return { privateKeyB64: identity.privateKey, publicKeyB64: identity.publicKey };
11855
11840
  },
11856
- resolutionQuery: async (input, requestSignal) => {
11857
- this.assertSyncAccount(userId), this.assertSyncReadAdmission(scope.sessionId);
11858
- try {
11859
- let response = await this.graphqlRequest(queries.getGateResolutionV2, { input }, !0, requestSignal, userId, 8192);
11860
- return this.assertSyncAccount(userId), this.assertSyncReadAdmission(scope.sessionId), _AppSyncClient.throwIfAborted(requestSignal), response?.data?.getGateResolutionV2;
11861
- } catch (error) {
11862
- throw this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(requestSignal), error instanceof AppSyncGraphQLError ? syncReadResponseError({ ok: !1, errorCode: error.responseMessage }) : error;
11863
- }
11864
- },
11841
+ // Retained Event-coordinate reads only. Product gate recovery uses the
11842
+ // canonical getGateResolution; no removed V2 query is wired here.
11865
11843
  getToken: async (requestSignal) => {
11866
11844
  if (this.assertSyncAccount(userId), this.tokens && this.tokens.expiresAt <= Date.now() && await this.refreshTokens(this.tokens, requestSignal), this.assertSyncAccount(userId), !this.tokens?.accessToken) throw new SyncEventClientError("SYNC_IDENTITY_UNAVAILABLE");
11867
11845
  return this.tokens.accessToken;
@@ -11963,13 +11941,7 @@ var AppSyncClient = class _AppSyncClient {
11963
11941
  },
11964
11942
  send: (action, input, signal) => (this.assertSyncAccount(userId), this.mutateDesktopSyncEvent(action, input, signal)),
11965
11943
  isQuotaDenial: (error) => error instanceof AppSyncGraphQLError && error.errorType === "SYNC_QUOTA_EXHAUSTED",
11966
- omitNewPayload: async (signal) => {
11967
- this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal);
11968
- let observed = this.companionSyncStatusSnapshot(userId), state = observed?.mode === "SHADOW" ? observed : await this.getCompanionSyncState(signal);
11969
- if (this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal), state.protocol !== "SYNC_V2" && !(state.mode === "SHADOW" && state.protocol === "LEGACY"))
11970
- throw new SyncEventClientError("SYNC_PRODUCER_FROZEN");
11971
- return state.usage?.syncState === "PAUSED";
11972
- }
11944
+ omitNewPayload: async (signal) => (this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal), !1)
11973
11945
  });
11974
11946
  }
11975
11947
  /** Closed metered tool producer; native source settlement owns journal acknowledgment. */
@@ -12142,56 +12114,64 @@ var AppSyncClient = class _AppSyncClient {
12142
12114
  } }), this.assertSyncAccount(userId);
12143
12115
  }
12144
12116
  /**
12145
- * Provider startup uses cloud routing, never a local tier/flag or an error
12146
- * fallback. A transport is generation-bound for its entire lifetime. Cutover
12147
- * and rollback must drain/restart the producer; they cannot reinterpret its
12148
- * sealed source windows as a different protocol.
12117
+ * Both producer formats use the existing createEvent API. Retained signed
12118
+ * sources keep their original generation and bytes; legacy sessions keep
12119
+ * their supported request shape. Neither format selects accounting policy.
12149
12120
  */
12150
12121
  async selectToolActivityTransport(options) {
12151
12122
  let { sessionId, root, legacyTransport } = options;
12152
12123
  if (typeof sessionId != "string" || !/^[A-Za-z0-9_-]{1,256}$/.test(sessionId) || legacyTransport.protocol !== void 0 && legacyTransport.protocol !== "LEGACY")
12153
12124
  throw new SyncEventClientError("INVALID_SYNC_INPUT");
12154
12125
  let selected = await this.selectCompanionSourceTransport({ sessionId, root });
12155
- return selected.protocol === "LEGACY" ? legacyTransport : this.toolActivitySyncTransport({
12126
+ if (selected.protocol === "LEGACY") return legacyTransport;
12127
+ let signed = this.toolActivitySyncTransport({
12156
12128
  root,
12157
12129
  sessionScope: selected.sessionScope,
12158
12130
  getEncryptionContext: selected.getEncryptionContext
12159
12131
  });
12132
+ return Object.freeze({ ...signed, sendRetainedLegacy: async (id5, envelope) => {
12133
+ if (id5 !== sessionId || envelope.backendSessionId !== sessionId || envelope.syncSessionGenerationId !== void 0)
12134
+ throw new SyncEventClientError("INVALID_SYNC_INPUT");
12135
+ if (await legacyTransport.send(id5, envelope) !== void 0) throw new SyncEventClientError("INVALID_SYNC_RECEIPT");
12136
+ } });
12160
12137
  }
12161
- /** Shared cloud-selected routing for tools and ordinary native sources. */
12138
+ /** Prepare request format from session identity, never quota/control mode.
12139
+ * SDK tags remain temporarily for existing source owners. They identify
12140
+ * journal formats, not different APIs or accounting policies. */
12162
12141
  async selectCompanionSourceTransport(options) {
12163
12142
  let { sessionId, root } = options;
12164
12143
  if (typeof sessionId != "string" || !/^[A-Za-z0-9_-]{1,256}$/.test(sessionId)) throw new SyncEventClientError("INVALID_SYNC_INPUT");
12165
12144
  let userId = this.getCurrentUserId();
12166
12145
  this.assertSyncAccount(userId);
12167
- let state = await this.getCompanionSyncRoute();
12168
- if (this.assertSyncAccount(userId), state.protocol === "FROZEN") throw new SyncEventClientError("SYNC_PRODUCER_FROZEN");
12169
- let existingGeneration = options.existingSessionGenerationId;
12170
- if (state.protocol === "LEGACY") {
12171
- if (this.companionSyncStatusSnapshot(userId)?.mode !== "SHADOW") {
12172
- if (existingGeneration === void 0) return Object.freeze({ protocol: "LEGACY" });
12173
- throw new SyncEventClientError("SYNC_PRODUCER_FROZEN");
12174
- }
12175
- if (existingGeneration === void 0) {
12176
- let generations = new Set([...this.syncRegistrations.get(sessionId)?.values() ?? []].filter((row3) => row3.userId === userId && (row3.scope.root ?? null) === (root ?? null)).map((row3) => row3.scope.sessionGenerationId));
12177
- if (!generations.size) return Object.freeze({ protocol: "LEGACY" });
12178
- if (generations.size !== 1) throw new SyncEventClientError("SYNC_SESSION_GENERATION_CHANGED");
12179
- existingGeneration = [...generations][0];
12180
- }
12181
- }
12146
+ let existingGeneration = options.existingSessionGenerationId, generations = new Set([...this.syncRegistrations.get(sessionId)?.values() ?? []].filter((row3) => row3.userId === userId && row3.signedProducer !== !1 && (row3.scope.root ?? null) === (root ?? null)).map((row3) => row3.scope.sessionGenerationId));
12147
+ if (generations.size > 1 || existingGeneration !== void 0 && [...generations].some((value) => value !== existingGeneration))
12148
+ throw new SyncEventClientError("SYNC_SESSION_GENERATION_CHANGED");
12149
+ existingGeneration ??= [...generations][0];
12182
12150
  let readSession = async () => {
12183
12151
  this.assertSyncAccount(userId);
12184
12152
  let session3 = await this.getSession(sessionId);
12185
- if (this.assertSyncAccount(userId), !session3 || session3.sessionId !== sessionId || session3.userId !== userId || session3.status !== "ACTIVE" || session3.isEncrypted !== !0 || typeof session3.sessionGenerationId != "string" || !/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(session3.sessionGenerationId))
12153
+ if (this.assertSyncAccount(userId), !session3 || session3.sessionId !== sessionId || session3.userId !== userId || session3.status !== "ACTIVE" || session3.sessionGenerationId != null && (typeof session3.sessionGenerationId != "string" || !/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(session3.sessionGenerationId)))
12186
12154
  throw new SyncEventClientError("SYNC_SESSION_UNAVAILABLE");
12187
12155
  return session3;
12188
- }, session2 = await readSession(), scope = Object.freeze({ sessionId, sessionGenerationId: session2.sessionGenerationId.toLowerCase() });
12156
+ }, session2 = await readSession();
12157
+ if (session2.sessionGenerationId == null || session2.isEncrypted !== !0) {
12158
+ if (existingGeneration !== void 0) throw new SyncEventClientError("SYNC_SESSION_GENERATION_CHANGED");
12159
+ return Object.freeze({ protocol: "LEGACY" });
12160
+ }
12161
+ let scope = Object.freeze({ sessionId, sessionGenerationId: session2.sessionGenerationId.toLowerCase() });
12189
12162
  if (existingGeneration !== void 0 && existingGeneration !== scope.sessionGenerationId)
12190
12163
  throw new SyncEventClientError("SYNC_SESSION_GENERATION_CHANGED");
12164
+ if (!await this.canSignDesktopSession(session2, userId)) {
12165
+ if (existingGeneration !== void 0) throw new SyncEventClientError("SYNC_IDENTITY_UNAVAILABLE");
12166
+ return Object.freeze({ protocol: "LEGACY" });
12167
+ }
12191
12168
  let getEncryptionContext = async () => {
12192
12169
  let current = await readSession();
12170
+ if (current.isEncrypted !== !0 || typeof current.sessionGenerationId != "string")
12171
+ throw new SyncEventClientError("SYNC_SESSION_UNAVAILABLE");
12193
12172
  if (current.sessionGenerationId.toLowerCase() !== scope.sessionGenerationId)
12194
12173
  throw new SyncEventClientError("SYNC_SESSION_GENERATION_CHANGED");
12174
+ if (!await this.canSignDesktopSession(current, userId)) throw new SyncEventClientError("SYNC_IDENTITY_UNAVAILABLE");
12195
12175
  let sessionKeyGen = current.sessionKeyGen ?? null, sessionKey = await keychainManager.getSessionKey(sessionId, current.encryptedKeys ?? [], sessionKeyGen);
12196
12176
  if (this.assertSyncAccount(userId), !sessionKey) throw new SyncEventClientError("SYNC_SESSION_KEY_UNAVAILABLE");
12197
12177
  return { ...scope, sessionKey, sessionKeyGen };
@@ -12225,6 +12205,20 @@ var AppSyncClient = class _AppSyncClient {
12225
12205
  }
12226
12206
  });
12227
12207
  }
12208
+ /** An ordinary subscription/reader is not authority to sign as the creator.
12209
+ * Read the existing identity only; never mint a replacement for this check. */
12210
+ async canSignDesktopSession(session2, userId) {
12211
+ if (session2.writerAttestationEligible !== !0 || !/^[a-f0-9]{64}$/.test(session2.creatorSigningKeySha256 ?? "")) return !1;
12212
+ let identity;
12213
+ try {
12214
+ identity = await keychainManager.getDeviceIdentity();
12215
+ } catch {
12216
+ return this.assertSyncAccount(userId), !1;
12217
+ }
12218
+ if (this.assertSyncAccount(userId), !identity?.privateKey || typeof identity.publicKey != "string") return !1;
12219
+ let raw = Buffer.from(identity.publicKey, "base64");
12220
+ return raw.length === 64 && raw.toString("base64") === identity.publicKey && (0, import_node_crypto17.createHash)("sha256").update(raw).digest("hex") === session2.creatorSigningKeySha256;
12221
+ }
12228
12222
  /** Shared E1 producer adapter. The legacy encryption factory runs only after
12229
12223
  * affirmative cloud LEGACY selection. V2 encrypts inside the durable source
12230
12224
  * factory and never maps a quota omission to a successful cloud publication. */
@@ -12310,14 +12304,14 @@ var AppSyncClient = class _AppSyncClient {
12310
12304
  producerKind: "PLUGIN_APPROVAL",
12311
12305
  ownerToken: input.ownerToken
12312
12306
  });
12313
- return this.resolvePromptByProtocol(control, () => control, async () => (await this.createEvent({
12307
+ return this.resolveOwnedPrompt(control, () => control, async () => (await this.createEvent({
12314
12308
  sessionId: input.sessionId,
12315
12309
  type: "NOTIFICATION" /* NOTIFICATION */,
12316
12310
  source: "DESKTOP" /* DESKTOP */,
12317
12311
  resolvedPromptId: input.promptId,
12318
12312
  ownerToken: input.ownerToken,
12319
12313
  ...input.resolutionAt !== void 0 && { resolutionAt: input.resolutionAt }
12320
- }))?.promptId === input.promptId, { root });
12314
+ }))?.promptId === input.promptId, { root }, !0);
12321
12315
  }
12322
12316
  /** Core resolution carries the generation already bound to the session
12323
12317
  * owner. Never fetch a newer Session/key to clear an older offer. */
@@ -12325,15 +12319,15 @@ var AppSyncClient = class _AppSyncClient {
12325
12319
  if (!value || typeof value != "object" || Array.isArray(value) || typeof legacy != "function" || Reflect.ownKeys(value).some((field2) => typeof field2 != "string" || !["sessionId", "promptId", "sessionGenerationId", "sessionKeyGen"].includes(field2)) || Object.values(Object.getOwnPropertyDescriptors(value)).some((d) => !d.enumerable || !("value" in d) || d.value !== void 0 && d.value !== null && typeof d.value != "string"))
12326
12320
  return Promise.reject(new SyncEventClientError("INVALID_SYNC_INPUT"));
12327
12321
  let input = { ...value }, userId = this.getCurrentUserId();
12328
- return this.resolvePromptByProtocol({ sessionId: input.sessionId, promptId: input.promptId }, () => makeSyncPromptResolutionInput(userId, {
12322
+ return this.resolveOwnedPrompt({ sessionId: input.sessionId, promptId: input.promptId }, () => makeSyncPromptResolutionInput(userId, {
12329
12323
  sessionId: input.sessionId,
12330
12324
  promptId: input.promptId,
12331
12325
  producerKind: "CORE_OFFER",
12332
12326
  sessionGenerationId: input.sessionGenerationId,
12333
12327
  expectedSessionKeyGen: input.sessionKeyGen ?? SESSION_KEY_GEN_ABSENT_SENTINEL
12334
- }), legacy, options);
12328
+ }), legacy, options, input.sessionGenerationId != null);
12335
12329
  }
12336
- resolvePromptByProtocol(scope, prepareV2, legacy, options) {
12330
+ resolveOwnedPrompt(scope, prepareControl, legacy, options, hasOriginalProof) {
12337
12331
  let userId = this.getCurrentUserId(), input = { sessionId: scope.sessionId, promptId: scope.promptId };
12338
12332
  if (typeof input.sessionId != "string" || !/^[A-Za-z0-9_-]{1,256}$/.test(input.sessionId) || typeof input.promptId != "string" || !/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(input.promptId))
12339
12333
  return Promise.reject(new SyncEventClientError("INVALID_SYNC_INPUT"));
@@ -12342,17 +12336,12 @@ var AppSyncClient = class _AppSyncClient {
12342
12336
  check();
12343
12337
  let resolutions = await writer.promptResolutions();
12344
12338
  check();
12345
- let knownV2 = [...publications, ...resolutions].some((row3) => row3.sessionId === input.sessionId && row3.promptId === input.promptId), durable = (control) => writer.runPromptResolution(control, async (saved, fence) => (await fence(), this.finishPromptResolution(saved, options, fence)));
12346
- if (knownV2) return durable(prepareV2());
12347
- let state = await this.getCompanionSyncRoute();
12348
- if (check(), state.protocol === "LEGACY")
12349
- return this.resolvePromptPublication(input, async (hasV2Publication) => {
12350
- if (hasV2Publication || (await writer.promptResolutions()).some((row3) => row3.sessionId === input.sessionId && row3.promptId === input.promptId))
12351
- throw new SyncEventClientError("SYNC_PRODUCER_FROZEN");
12352
- return check(), legacy();
12353
- }, options);
12354
- if (state.protocol !== "SYNC_V2") throw new SyncEventClientError("SYNC_PRODUCER_FROZEN");
12355
- return durable(prepareV2());
12339
+ let knownSigned = [...publications, ...resolutions].some((row3) => row3.sessionId === input.sessionId && row3.promptId === input.promptId), durable = (control) => writer.runPromptResolution(control, async (saved, fence) => (await fence(), this.finishPromptResolution(saved, options, fence)));
12340
+ return knownSigned || hasOriginalProof ? durable(prepareControl()) : this.resolvePromptPublication(input, async (hasV2Publication) => {
12341
+ if (hasV2Publication || (await writer.promptResolutions()).some((row3) => row3.sessionId === input.sessionId && row3.promptId === input.promptId))
12342
+ throw new SyncEventClientError("SYNC_SESSION_GENERATION_CHANGED");
12343
+ return check(), legacy();
12344
+ }, options);
12356
12345
  })();
12357
12346
  return this.trackSyncClosure(input.sessionId, work.then(() => {
12358
12347
  }, () => {
@@ -12440,8 +12429,8 @@ var AppSyncClient = class _AppSyncClient {
12440
12429
  userId,
12441
12430
  { privateKeyB64: identity.privateKey, publicKeyB64: identity.publicKey },
12442
12431
  Date.now()
12443
- ), response = await this.graphqlRequest(mutations.confirmSessionRetirementV2, { input: prepared }, !1, signal, userId);
12444
- return this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal), parseSyncSessionRetirementReceipt(response?.data?.confirmSessionRetirementV2, data);
12432
+ ), response = await this.graphqlRequest(mutations.confirmSessionRetirement, { input: prepared }, !1, signal, userId);
12433
+ return this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal), parseSyncSessionRetirementReceipt(response?.data?.confirmSessionRetirement, data);
12445
12434
  }
12446
12435
  /** Explicit terminal owner boundary. quiesce must stop AND join native,
12447
12436
  * shell, prompt and source-recovery producers; a daemon handoff is not a
@@ -12557,8 +12546,22 @@ var AppSyncClient = class _AppSyncClient {
12557
12546
  Date.now()
12558
12547
  );
12559
12548
  }
12560
- let response = await this.graphqlRequest(mutations.resolveOpenPromptV2, { input: prepared }, !1, signal, userId);
12561
- return this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal), parseSyncPromptResolutionReceipt(response?.data?.resolveOpenPromptV2, data);
12549
+ let response = await this.graphqlRequest(mutations.createEvent, { input: {
12550
+ ...prepared,
12551
+ type: "NOTIFICATION",
12552
+ source: "DESKTOP",
12553
+ resolvedPromptId: data.promptId
12554
+ } }, !1, signal, userId);
12555
+ this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal);
12556
+ let ack = response?.data?.createEvent;
12557
+ if (!ack || typeof ack != "object" || Array.isArray(ack) || typeof ack.sessionId != "string" || !/^__blocked__[0-9a-f-]{36}$/.test(ack.sessionId) || ack.type !== "NOTIFICATION" || ack.source !== "DESKTOP" || ack.emittedBy !== "SYSTEM" || ack.promptId !== data.promptId)
12558
+ throw new SyncEventClientError("INVALID_SYNC_RECEIPT");
12559
+ return parseSyncPromptResolutionReceipt({
12560
+ sessionId: data.sessionId,
12561
+ promptId: ack.promptId,
12562
+ state: "RESOLVED",
12563
+ controlClass: "PROMPT_OWNERSHIP"
12564
+ }, data);
12562
12565
  }
12563
12566
  /** Monotonic control transition; safe retry means re-read canonical status,
12564
12567
  * not retrying the provider input or manufacturing a full Event response. */
@@ -12574,52 +12577,71 @@ var AppSyncClient = class _AppSyncClient {
12574
12577
  userId,
12575
12578
  { privateKeyB64: identity.privateKey, publicKeyB64: identity.publicKey },
12576
12579
  Date.now()
12577
- ), response = await this.graphqlRequest(mutations.updateEventStatusV2, { input: prepared }, !1, signal, userId);
12578
- return this.assertSyncAccount(userId), parseSyncStatusReceipt(response?.data?.updateEventStatusV2, data);
12580
+ ), response = await this.graphqlRequest(mutations.updateEventStatus, { input: prepared }, !1, signal, userId);
12581
+ this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal);
12582
+ let event = response?.data?.updateEventStatus;
12583
+ if (!event || typeof event != "object" || Array.isArray(event)) throw new SyncEventClientError("INVALID_SYNC_RECEIPT");
12584
+ return parseSyncStatusReceipt({
12585
+ sessionId: event.sessionId,
12586
+ sessionGenerationId: event.sessionGenerationId ?? data.sessionGenerationId,
12587
+ eventId: event.eventId,
12588
+ timestamp: event.timestamp,
12589
+ type: event.type,
12590
+ source: event.source,
12591
+ deliveryStatus: event.deliveryStatus,
12592
+ deliveredAt: event.deliveredAt,
12593
+ ...event.executedAt !== void 0 && event.executedAt !== null && { executedAt: event.executedAt }
12594
+ }, data);
12579
12595
  }
12580
- /** One budgeted liveness operation, never a legacy fallback. The producer
12581
- * must persist each receipt/progress before advancing its refresh batch. */
12596
+ /** Compatibility helper over the existing batch API; no expiry is invented. */
12582
12597
  async refreshDesktopSyncPrompt(promptId2, signal) {
12583
12598
  if (_AppSyncClient.throwIfAborted(signal), typeof promptId2 != "string" || !/^[A-Za-z0-9_-]{1,256}$/.test(promptId2))
12584
12599
  throw new SyncEventClientError("INVALID_SYNC_INPUT");
12585
- let userId = this.getCurrentUserId();
12586
- this.assertSyncAccount(userId);
12587
- let response = await this.graphqlRequest(mutations.refreshOpenPromptTtlV2, { promptId: promptId2 }, !1, signal, userId);
12588
- return this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal), parseSyncPromptRetentionReceipt(response?.data?.refreshOpenPromptTtlV2, promptId2);
12600
+ let missing = await this.refreshOpenPromptTtl([promptId2], signal);
12601
+ return parseSyncPromptRetentionReceipt({
12602
+ promptId: promptId2,
12603
+ status: missing.includes(promptId2) ? "RERAISE_REQUIRED" : "REFRESHED"
12604
+ }, promptId2);
12589
12605
  }
12590
- /** Producer-facing batch: V2 keeps exact per-incarnation progress; the
12591
- * legacy protocol retains its existing chunked endpoint until cutover. */
12606
+ /** One canonical batch route. Retained generations identify only the local
12607
+ * re-raise journal; they cannot select a cloud API or accounting policy. */
12592
12608
  async refreshSessionOpenPromptTtl(options, reRaise) {
12593
12609
  let { sessionId, root } = options, promptIds = [...options.promptIds];
12594
12610
  if (!promptIds.length) return;
12595
12611
  let userId = this.getCurrentUserId();
12596
12612
  this.assertSyncAccount(userId), this.assertSyncReadAdmission(sessionId);
12597
- let selected = await this.selectCompanionSourceTransport({ sessionId, root });
12598
- if (this.assertSyncAccount(userId), this.assertSyncReadAdmission(sessionId), selected.protocol === "LEGACY") {
12599
- let missing = await this.refreshOpenPromptTtl(promptIds);
12600
- this.assertSyncAccount(userId);
12601
- for (let promptId2 of missing) {
12602
- if (this.assertSyncReadAdmission(sessionId), await reRaise(promptId2) === "RETRY") throw new Error("SYNC_PROMPT_RERAISE_PENDING");
12603
- this.assertSyncAccount(userId);
12604
- }
12605
- return;
12606
- }
12607
- this.rememberSyncRegistration({ ...selected.sessionScope, root });
12613
+ let retained = await this.desktopSyncWriter({ root }).promptRetentionScopes(), generations = new Set([...this.syncRegistrations.get(sessionId)?.values() ?? []].filter((row3) => row3.userId === userId && (row3.scope.root ?? null) === (root ?? null)).map((row3) => row3.scope.sessionGenerationId));
12614
+ this.assertSyncAccount(userId), this.assertSyncReadAdmission(sessionId);
12608
12615
  let check = () => {
12609
12616
  this.assertSyncAccount(userId), this.assertSyncReadAdmission(sessionId);
12610
- }, work = selected.writer.promptRetention().run(
12611
- promptIds,
12612
- async (promptId2) => {
12613
- check();
12614
- let result = await this.refreshDesktopSyncPrompt(promptId2);
12615
- return check(), result;
12616
- },
12617
- async (promptId2, token4) => {
12618
- check();
12619
- let result = await reRaise(promptId2, token4);
12620
- return check(), result;
12621
- }
12622
- );
12617
+ }, batch, refresh = async (promptId2) => {
12618
+ check(), batch ??= this.refreshOpenPromptTtl(promptIds).then((missing2) => new Set(missing2));
12619
+ let missing = await batch;
12620
+ return check(), { promptId: promptId2, status: missing.has(promptId2) ? "RERAISE_REQUIRED" : "REFRESHED" };
12621
+ }, raise = async (promptId2, token4) => {
12622
+ check();
12623
+ let result = await reRaise(promptId2, token4);
12624
+ return check(), result;
12625
+ }, work = (async () => {
12626
+ let handled = /* @__PURE__ */ new Set();
12627
+ for (let owner of retained.filter((scope) => scope.sessionId === sessionId)) {
12628
+ let owned = promptIds.filter((id5) => owner.promptIds.includes(id5));
12629
+ if (!owned.length) continue;
12630
+ let sessionScope = { sessionId, sessionGenerationId: owner.sessionGenerationId };
12631
+ await this.desktopSyncWriter({ root, sessionScope }).promptRetention().run(owned, refresh, raise);
12632
+ for (let id5 of owned) handled.add(id5);
12633
+ }
12634
+ let remaining = promptIds.filter((id5) => !handled.has(id5));
12635
+ if (remaining.length)
12636
+ if (generations.size === 1) {
12637
+ let sessionScope = { sessionId, sessionGenerationId: [...generations][0] };
12638
+ await this.desktopSyncWriter({ root, sessionScope }).promptRetention().run(remaining, refresh, raise);
12639
+ } else {
12640
+ let missing = await this.refreshOpenPromptTtl(remaining);
12641
+ check();
12642
+ for (let id5 of missing) if (await raise(id5) === "RETRY") throw new Error("SYNC_PROMPT_RERAISE_PENDING");
12643
+ }
12644
+ })();
12623
12645
  this.trackSyncClosure(sessionId, work.then(() => {
12624
12646
  }, () => {
12625
12647
  })), await work;
@@ -12644,7 +12666,7 @@ var AppSyncClient = class _AppSyncClient {
12644
12666
  userId,
12645
12667
  { privateKeyB64: identity.privateKey, publicKeyB64: identity.publicKey },
12646
12668
  Date.now()
12647
- ), field2 = action === "CREATE_EVENT" ? "createEventV2" : "updateEventV2", response;
12669
+ ), field2 = action === "CREATE_EVENT" ? "createEvent" : "updateEvent", response;
12648
12670
  try {
12649
12671
  response = await this.graphqlRequest(mutations[field2], { input: prepared }, !1, signal, userId, void 0, check);
12650
12672
  } catch (error) {
@@ -12668,15 +12690,13 @@ var AppSyncClient = class _AppSyncClient {
12668
12690
  throw error;
12669
12691
  }
12670
12692
  this.assertSyncAccount(userId);
12671
- let result = parseSyncEventMutationResponse(response?.data?.[field2], data);
12672
- if (result.refreshSyncState) {
12673
- try {
12674
- await this.getCompanionSyncState(signal);
12675
- } catch {
12676
- }
12677
- this.assertSyncAccount(userId);
12678
- }
12679
- return result.receipt;
12693
+ let value = response?.data?.[field2];
12694
+ if (!value || typeof value != "object" || Array.isArray(value))
12695
+ throw new SyncEventClientError("INVALID_SYNC_RECEIPT");
12696
+ return parseSyncEventReceipt(
12697
+ Object.fromEntries(["eventId", "sessionId", "type", "source", "timestamp", "emittedBy"].map((key) => [key, value[key]])),
12698
+ data
12699
+ );
12680
12700
  }
12681
12701
  /**
12682
12702
  * Create a session
@@ -12802,27 +12822,13 @@ var AppSyncClient = class _AppSyncClient {
12802
12822
  // MARK: - Event Operations
12803
12823
  /** The workspace owner retains its existing durable outbox. Never put a
12804
12824
  * second journal around it, re-encrypt it, or choose the current generation.
12805
- * Quota omission is a canonical ACK, not a synthetic Event or a retry queue.
12825
+ * Existing createEvent owns cloud policy and returns its authenticated Event.
12806
12826
  */
12807
12827
  async submitWorkspaceOutcome(value, options = {}) {
12808
12828
  let input = snapshotWorkspaceOutcomeInput(value), userId = this.getCurrentUserId();
12809
- this.assertSyncAccount(userId);
12810
- let route = await this.getCompanionSyncRoute();
12811
- if (this.assertSyncAccount(userId), route.protocol === "FROZEN") throw new SyncEventClientError("SYNC_PRODUCER_FROZEN");
12812
- if (route.protocol === "LEGACY") {
12813
- if (options.requiresV2) throw new SyncEventClientError("SYNC_PRODUCER_FROZEN");
12814
- let result = await this.createEvent(input);
12815
- return this.assertSyncAccount(userId), legacyWorkspaceOutcomeReceipt(result, input);
12816
- }
12817
- await options.beforeV2?.(), this.assertSyncAccount(userId);
12818
- let response = await this.graphqlRequest(
12819
- mutations.recordWorkspaceOutcomeV2,
12820
- { input: JSON.stringify(input) },
12821
- !1,
12822
- void 0,
12823
- userId
12824
- );
12825
- return this.assertSyncAccount(userId), parseWorkspaceOutcomeReceipt(response?.data?.recordWorkspaceOutcomeV2, input);
12829
+ this.assertSyncAccount(userId), await options.beforeV2?.(), this.assertSyncAccount(userId);
12830
+ let event = await this.createEvent(input);
12831
+ return this.assertSyncAccount(userId), workspaceOutcomeEventReceipt(event, input);
12826
12832
  }
12827
12833
  /**
12828
12834
  * Create an event
@@ -12882,14 +12888,20 @@ var AppSyncClient = class _AppSyncClient {
12882
12888
  * row/Event had already aged out — the caller re-raises those (§6a-4
12883
12889
  * return-driven re-raise). No-ops on an empty list (no network call).
12884
12890
  */
12885
- async refreshOpenPromptTtl(promptIds) {
12886
- if (promptIds.length === 0) return [];
12887
- let MAX_BATCH = 100;
12888
- if (promptIds.length <= MAX_BATCH)
12889
- return (await this.graphqlRequest(mutations.refreshOpenPromptTtl, { promptIds })).data?.refreshOpenPromptTtl ?? [];
12890
- let agedOut = [];
12891
- for (let i = 0; i < promptIds.length; i += MAX_BATCH) {
12892
- let chunk = promptIds.slice(i, i + MAX_BATCH), returned = (await this.graphqlRequest(mutations.refreshOpenPromptTtl, { promptIds: chunk })).data?.refreshOpenPromptTtl ?? [];
12891
+ async refreshOpenPromptTtl(promptIds, signal) {
12892
+ let ids = [...new Set(promptIds)];
12893
+ if (ids.length > 4096 || ids.some((id5) => typeof id5 != "string" || !/^[A-Za-z0-9_-]{1,256}$/.test(id5)))
12894
+ throw new SyncEventClientError("INVALID_SYNC_INPUT");
12895
+ if (_AppSyncClient.throwIfAborted(signal), ids.length === 0) return [];
12896
+ let userId = this.getCurrentUserId();
12897
+ this.assertSyncAccount(userId);
12898
+ let MAX_BATCH = 100, agedOut = [];
12899
+ for (let i = 0; i < ids.length; i += MAX_BATCH) {
12900
+ let chunk = ids.slice(i, i + MAX_BATCH), response = await this.graphqlRequest(mutations.refreshOpenPromptTtl, { promptIds: chunk }, !1, signal, userId);
12901
+ this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal);
12902
+ let returned = response.data?.refreshOpenPromptTtl;
12903
+ if (!Array.isArray(returned) || new Set(returned).size !== returned.length || returned.some((id5) => typeof id5 != "string" || !chunk.includes(id5)))
12904
+ throw new SyncEventClientError("INVALID_SYNC_RECEIPT");
12893
12905
  returned.length > 0 && agedOut.push(...returned);
12894
12906
  }
12895
12907
  return agedOut;
@@ -12911,19 +12923,19 @@ var AppSyncClient = class _AppSyncClient {
12911
12923
  source: "MOBILE" /* MOBILE */,
12912
12924
  type: expected.type
12913
12925
  }), this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal));
12914
- let route = await this.getCompanionSyncRoute(signal);
12915
- if (this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal), route.protocol === "FROZEN") throw new SyncEventClientError("SYNC_PRODUCER_FROZEN");
12916
- if (requiredSessionGenerationId !== void 0 && route.protocol !== "SYNC_V2") throw new SyncEventClientError("SYNC_PRODUCER_FROZEN");
12917
- if (route.protocol === "LEGACY") {
12926
+ let scopes = [...this.syncRegistrations.get(input.sessionId)?.values() ?? []].filter((row3) => row3.userId === userId);
12927
+ if (requiredSessionGenerationId === void 0 && !scopes.some((row3) => row3.signedProducer !== !1)) {
12918
12928
  let response = await this.graphqlRequest(mutations.updateEventStatus, { input }, !1, signal, userId);
12919
12929
  return this.assertSyncAccount(userId), response.data.updateEventStatus;
12920
12930
  }
12921
12931
  if (input.deliveryStatus !== "DELIVERED" && input.deliveryStatus !== "EXECUTED") throw new SyncEventClientError("INVALID_SYNC_INPUT");
12922
12932
  let session2 = await this.getSession(input.sessionId);
12923
12933
  if (this.assertSyncAccount(userId), _AppSyncClient.throwIfAborted(signal), !session2 || session2.sessionId !== input.sessionId || session2.userId !== userId || session2.status !== "ACTIVE" || typeof session2.sessionGenerationId != "string") throw new SyncEventClientError("SYNC_SESSION_UNAVAILABLE");
12924
- let scopes = [...this.syncRegistrations.get(input.sessionId)?.values() ?? []].filter((row3) => row3.userId === userId), generation = session2.sessionGenerationId.toLowerCase();
12934
+ let generation = session2.sessionGenerationId.toLowerCase();
12925
12935
  if (requiredSessionGenerationId !== void 0 && generation !== requiredSessionGenerationId) throw new SyncEventClientError("SYNC_SESSION_GENERATION_CHANGED");
12926
12936
  if (scopes.length && !scopes.some((row3) => row3.scope.sessionGenerationId === generation)) throw new SyncEventClientError("SYNC_SESSION_GENERATION_CHANGED");
12937
+ if (!await this.canSignDesktopSession(session2, userId)) throw new SyncEventClientError("SYNC_IDENTITY_UNAVAILABLE");
12938
+ _AppSyncClient.throwIfAborted(signal);
12927
12939
  let receipt2 = await this.updateDesktopSyncEventStatus({
12928
12940
  ...input,
12929
12941
  clientOperationId: (0, import_uuid5.v4)(),
@@ -12939,13 +12951,16 @@ var AppSyncClient = class _AppSyncClient {
12939
12951
  * List events for a session
12940
12952
  */
12941
12953
  async listEvents(sessionId, source2, limit) {
12942
- let route = await this.getCompanionSyncRoute();
12943
- if (route.protocol === "FROZEN") throw new SyncEventClientError("SYNC_PRODUCER_FROZEN");
12944
- if (route.protocol === "SYNC_V2") {
12945
- if (limit !== void 0 && (!Number.isSafeInteger(limit) || limit < 1 || limit > 100)) throw new SyncEventClientError("INVALID_SYNC_INPUT");
12946
- return (await this.syncHistoryForSession(sessionId)).items.filter((event) => source2 === void 0 || event.source === source2).slice(0, limit ?? 100);
12947
- }
12948
- return (await this.graphqlRequest(queries.listEvents, { sessionId, source: source2, limit })).data.listEvents.items;
12954
+ let userId = this.getCurrentUserId(), epoch = this.syncReadEpoch;
12955
+ this.assertSyncAccount(userId), this.assertSyncReadAdmission(sessionId);
12956
+ let response = await this.graphqlRequest(queries.listEvents, { sessionId, source: source2, limit }, !1, void 0, userId);
12957
+ if (this.assertSyncAccount(userId), this.assertSyncReadAdmission(sessionId), epoch !== this.syncReadEpoch) throw new SyncEventClientError("SYNC_SESSION_UNAVAILABLE");
12958
+ let items = response.data?.listEvents?.items;
12959
+ if (!Array.isArray(items)) throw new Error("listEvents returned an invalid page");
12960
+ let expectedGeneration = this.activeSubscriptions.get(sessionId)?.syncSessionGenerationId;
12961
+ if (items.some((item2) => !item2 || item2.sessionId !== sessionId || expectedGeneration && item2.sessionGenerationId != null && item2.sessionGenerationId !== expectedGeneration))
12962
+ throw new SyncReadClientError("INVALID_SYNC_READ_RESPONSE");
12963
+ return items;
12949
12964
  }
12950
12965
  /**
12951
12966
  * Strongly-consistent, paginated supervision history used to close the
@@ -12953,13 +12968,11 @@ var AppSyncClient = class _AppSyncClient {
12953
12968
  * can merge each page through the same strict event classifier as live data.
12954
12969
  */
12955
12970
  async listSupervisionEvents(input) {
12956
- let route = await this.getCompanionSyncRoute();
12957
- if (route.protocol === "FROZEN") throw new SyncEventClientError("SYNC_PRODUCER_FROZEN");
12958
- if (route.protocol === "SYNC_V2") {
12959
- if (input.limit !== void 0 && input.limit !== 100) throw new SyncEventClientError("INVALID_SYNC_INPUT");
12960
- return this.syncHistoryForSession(input.sessionId, input.sessionGenerationId, input.nextToken);
12961
- }
12962
- let page = (await this.graphqlRequest(queries.listSupervisionEvents, input)).data?.listSupervisionEvents;
12971
+ let expected = { ...input }, userId = this.getCurrentUserId(), epoch = this.syncReadEpoch;
12972
+ this.assertSyncAccount(userId), this.assertSyncReadAdmission(expected.sessionId);
12973
+ let response = await this.graphqlRequest(queries.listSupervisionEvents, expected, !1, void 0, userId);
12974
+ if (this.assertSyncAccount(userId), this.assertSyncReadAdmission(expected.sessionId), epoch !== this.syncReadEpoch) throw new SyncEventClientError("SYNC_SESSION_UNAVAILABLE");
12975
+ let page = response.data?.listSupervisionEvents;
12963
12976
  if (!page || !Array.isArray(page.items))
12964
12977
  throw new Error("listSupervisionEvents returned an invalid page");
12965
12978
  if (page.nextToken !== void 0 && page.nextToken !== null && typeof page.nextToken != "string")
@@ -13397,18 +13410,18 @@ var AppSyncClient = class _AppSyncClient {
13397
13410
  * result is deliberately not subscribed: it fences the submitting client but
13398
13411
  * never stands in for the durable GATE_RESOLUTION Event.
13399
13412
  */
13400
- async submitGateDecisionV2(request3, canonicalRequestHash) {
13401
- let { promptKind: _promptKind, ...semanticInput } = request3, response = await this.graphqlRequest(mutations.submitGateDecisionV2, {
13413
+ async submitGateDecision(request3, canonicalRequestHash) {
13414
+ let { promptKind: _promptKind, ...semanticInput } = request3, response = await this.graphqlRequest(mutations.submitGateDecision, {
13402
13415
  input: { ...semanticInput, canonicalRequestHash }
13403
13416
  });
13404
- return parseDecisionSubmissionResult(response.data?.submitGateDecisionV2);
13417
+ return parseDecisionSubmissionResult(response.data?.submitGateDecision);
13405
13418
  }
13406
13419
  /** P16/P20 TaskGroup-native decision admission (CLAIM, not workflow COMMIT). */
13407
- async submitGroupDecisionV2(request3, canonicalRequestHash) {
13408
- let { promptKind: _promptKind, ...semanticInput } = request3, response = await this.graphqlRequest(mutations.submitGroupDecisionV2, {
13420
+ async submitGroupDecision(request3, canonicalRequestHash) {
13421
+ let { promptKind: _promptKind, ...semanticInput } = request3, response = await this.graphqlRequest(mutations.submitGroupDecision, {
13409
13422
  input: { ...semanticInput, canonicalRequestHash }
13410
13423
  });
13411
- return parseDecisionSubmissionResult(response.data?.submitGroupDecisionV2);
13424
+ return parseDecisionSubmissionResult(response.data?.submitGroupDecision);
13412
13425
  }
13413
13426
  async authorizeGroupTerminalOperation(input) {
13414
13427
  let response = await this.graphqlRequest(mutations.authorizeGroupTerminalOperation, { input });
@@ -13434,46 +13447,29 @@ var AppSyncClient = class _AppSyncClient {
13434
13447
  let response = await this.graphqlRequest(mutations.prepareGroupKeep, { input });
13435
13448
  return parseGroupOperationResult(response.data?.prepareGroupKeep, "prepareGroupKeep");
13436
13449
  }
13437
- async commitGroupDecisionV2(input) {
13438
- let response = await this.graphqlRequest(mutations.commitGroupDecisionV2, { input });
13439
- return parseGroupDecisionCommitResult(response.data?.commitGroupDecisionV2);
13450
+ async commitGroupDecision(input) {
13451
+ let response = await this.graphqlRequest(mutations.commitGroupDecision, { input });
13452
+ return parseGroupDecisionCommitResult(response.data?.commitGroupDecision);
13440
13453
  }
13441
13454
  /** Owner-scoped recovery point-read for a locally durable attempt receipt. */
13442
13455
  async getDecisionAttempt(input) {
13443
13456
  let response = await this.graphqlRequest(queries.getDecisionAttempt, { input });
13444
13457
  return parseDecisionAttemptResult(response.data?.getDecisionAttempt);
13445
13458
  }
13446
- /** Cloud-selected recovery protocol. V2 requires the session owner's known
13447
- * generation and never falls back to a live Session lookup or legacy Event. */
13459
+ /** One canonical recovery API. The cloud verifies owner/history authority
13460
+ * and, when supplied, the exact generation. No accounting-route/status read
13461
+ * or second delivery transport may block decision recovery. */
13448
13462
  async getGateResolution(input) {
13449
13463
  let expected = { ...input }, userId = this.getCurrentUserId(), epoch = this.syncReadEpoch;
13450
- this.assertSyncAccount(userId), this.assertSyncReadAdmission(expected.sessionId);
13451
- let route = await this.getCompanionSyncRoute();
13464
+ this.assertSyncAccount(userId), this.assertSyncReadAdmission(expected.sessionId), expected.sessionGenerationId !== void 0 && validateSyncResolutionScope(
13465
+ { ...expected, sessionGenerationId: expected.sessionGenerationId },
13466
+ () => {
13467
+ throw new SyncReadClientError("INVALID_SYNC_READ_INPUT");
13468
+ }
13469
+ );
13470
+ let response = await this.graphqlRequest(queries.getGateResolution, { input: expected }, !1, void 0, userId);
13452
13471
  if (this.assertSyncAccount(userId), this.assertSyncReadAdmission(expected.sessionId), epoch !== this.syncReadEpoch) throw new SyncEventClientError("SYNC_SESSION_UNAVAILABLE");
13453
- if (route.protocol === "LEGACY") {
13454
- let response = await this.graphqlRequest(
13455
- queries.getGateResolution,
13456
- { input: { sessionId: expected.sessionId, promptId: expected.promptId } },
13457
- !1,
13458
- void 0,
13459
- userId
13460
- );
13461
- if (this.assertSyncAccount(userId), this.assertSyncReadAdmission(expected.sessionId), epoch !== this.syncReadEpoch) throw new SyncEventClientError("SYNC_SESSION_UNAVAILABLE");
13462
- return response.data?.getGateResolution;
13463
- }
13464
- if (route.protocol !== "SYNC_V2") throw new SyncEventClientError("SYNC_PRODUCER_FROZEN");
13465
- if (!expected.sessionGenerationId) throw new SyncReadClientError("INVALID_SYNC_READ_INPUT");
13466
- validateSyncResolutionScope({ ...expected, sessionGenerationId: expected.sessionGenerationId }, () => {
13467
- throw new SyncReadClientError("INVALID_SYNC_READ_INPUT");
13468
- });
13469
- let reader = await this.desktopSyncReadSession({ sessionId: expected.sessionId, sessionGenerationId: expected.sessionGenerationId });
13470
- try {
13471
- let result = await reader.gateResolution(expected.promptId);
13472
- if (this.assertSyncAccount(userId), this.assertSyncReadAdmission(expected.sessionId), epoch !== this.syncReadEpoch) throw new SyncEventClientError("SYNC_SESSION_UNAVAILABLE");
13473
- return result;
13474
- } finally {
13475
- await reader.close();
13476
- }
13472
+ return response.data?.getGateResolution;
13477
13473
  }
13478
13474
  async applyUserDecision(input, sessionKeyBase64) {
13479
13475
  let encryptedNotes = null;
@@ -14378,12 +14374,12 @@ var AppSyncClient = class _AppSyncClient {
14378
14374
  assertSyncReadAdmission(sessionId) {
14379
14375
  if (this.syncRetiringSessions.has(sessionId)) throw new SyncEventClientError("SYNC_SESSION_UNAVAILABLE");
14380
14376
  }
14381
- rememberSyncRegistration(scope) {
14382
- let userId = this.getCurrentUserId(), rows = this.syncRegistrations.get(scope.sessionId) ?? /* @__PURE__ */ new Map();
14383
- rows.set(JSON.stringify([userId, scope.sessionGenerationId, scope.root ?? null]), { userId, scope: { ...scope } }), this.syncRegistrations.set(scope.sessionId, rows);
14377
+ rememberSyncRegistration(scope, signedProducer = !0) {
14378
+ let userId = this.getCurrentUserId(), rows = this.syncRegistrations.get(scope.sessionId) ?? /* @__PURE__ */ new Map(), key = JSON.stringify([userId, scope.sessionGenerationId, scope.root ?? null]);
14379
+ rows.set(key, { userId, scope: { ...scope }, signedProducer: signedProducer || rows.get(key)?.signedProducer === !0 }), this.syncRegistrations.set(scope.sessionId, rows);
14384
14380
  }
14385
14381
  ownSyncReader(scope, reader) {
14386
- this.rememberSyncRegistration(scope);
14382
+ this.rememberSyncRegistration(scope, !1);
14387
14383
  let owners = this.syncReadOwners.get(scope.sessionId) ?? /* @__PURE__ */ new Set();
14388
14384
  this.syncReadOwners.set(scope.sessionId, owners);
14389
14385
  let closing, owner = Object.freeze({ ...reader, close: () => closing || (closing = reader.close().finally(() => {
@@ -14402,20 +14398,6 @@ var AppSyncClient = class _AppSyncClient {
14402
14398
  let pending = this.syncSubscriptionClosures.get(sessionId);
14403
14399
  pending && await Promise.all([...pending]);
14404
14400
  }
14405
- async syncHistoryForSession(sessionId, sessionGenerationId, nextToken) {
14406
- this.assertSyncReadAdmission(sessionId);
14407
- let userId = this.getCurrentUserId(), session2 = await this.getSession(sessionId);
14408
- if (this.assertSyncAccount(userId), this.assertSyncReadAdmission(sessionId), session2?.sessionId !== sessionId || !session2.sessionGenerationId || session2.userId !== userId || sessionGenerationId !== void 0 && sessionGenerationId !== session2.sessionGenerationId)
14409
- throw new SyncEventClientError("SYNC_SESSION_UNAVAILABLE");
14410
- let scope = { sessionId, sessionGenerationId: session2.sessionGenerationId }, state = this.activeSubscriptions.get(sessionId), live = !state?.destroyed && state?.syncSessionGenerationId === scope.sessionGenerationId ? state.syncConnection : void 0, reader = live ?? await this.desktopSyncReadSession(scope);
14411
- try {
14412
- let page = await reader.history(nextToken);
14413
- if (this.assertSyncAccount(userId), this.assertSyncReadAdmission(sessionId), page.sessionId !== scope.sessionId || page.sessionGenerationId !== scope.sessionGenerationId) throw new SyncReadClientError("INVALID_SYNC_READ_RESPONSE");
14414
- return { items: page.items.map((event) => this.syncEventForConsumer(event)), nextToken: page.nextToken };
14415
- } finally {
14416
- live || await reader.close();
14417
- }
14418
- }
14419
14401
  /**
14420
14402
  * Subscribe to events for a session
14421
14403
  */
@@ -14480,41 +14462,49 @@ var AppSyncClient = class _AppSyncClient {
14480
14462
  createSubscription(state) {
14481
14463
  let abort = state.setupAbort = new AbortController(), current = () => !state.destroyed && !abort.signal.aborted && this.activeSubscriptions.get(state.sessionId) === state, setup = (async () => {
14482
14464
  if (await this.joinSyncSubscriptionClosures(state.sessionId), !current()) return;
14483
- let userId = this.getCurrentUserId(), route = await this.getCompanionSyncRoute(abort.signal);
14484
- if (!current()) return;
14485
- if (this.assertSyncAccount(userId), route.protocol === "FROZEN") throw new SyncEventClientError("SYNC_PRODUCER_FROZEN");
14486
- if (route.protocol === "LEGACY") {
14487
- this.createLegacySubscription(state);
14488
- return;
14489
- }
14465
+ let userId = this.getCurrentUserId();
14466
+ this.assertSyncAccount(userId);
14490
14467
  let session2 = await this.getSession(state.sessionId);
14491
14468
  if (!current()) return;
14492
- if (this.assertSyncAccount(userId), !session2?.sessionGenerationId || session2.userId !== userId || !["ACTIVE" /* ACTIVE */, "PAUSED" /* PAUSED */].includes(session2.status)) throw new SyncEventClientError("SYNC_SESSION_UNAVAILABLE");
14493
- let generation = session2.sessionGenerationId, connection = await this.desktopSyncLiveSession(
14494
- {
14495
- sessionId: state.sessionId,
14496
- sessionGenerationId: generation,
14497
- revalidateRegistration: state.syncRegistrationRevalidationGeneration === generation,
14498
- onRegistrationRevalidated: () => {
14499
- current() && (state.syncRegistrationRevalidatedGeneration = generation, delete state.syncRegistrationRevalidationGeneration);
14469
+ if (this.assertSyncAccount(userId), !session2 || session2.userId !== userId || !["ACTIVE" /* ACTIVE */, "PAUSED" /* PAUSED */].includes(session2.status))
14470
+ throw new SyncEventClientError("SYNC_SESSION_UNAVAILABLE");
14471
+ let retainedIds = /* @__PURE__ */ new Set();
14472
+ state.mobileInputRecoveryHeld = !1, session2.sessionGenerationId && (state.compatibilityInboundIds = retainedIds, state.syncSessionGenerationId = session2.sessionGenerationId), this.createLegacySubscription(state), !(!session2.sessionGenerationId || !current()) && (async () => {
14473
+ try {
14474
+ let scope = { sessionId: state.sessionId, sessionGenerationId: session2.sessionGenerationId }, coordinates = await this.desktopSyncWriter({ sessionScope: scope }).inbound().retainedCoordinates();
14475
+ if (!current()) return;
14476
+ this.assertSyncAccount(userId);
14477
+ for (let target2 of coordinates) retainedIds.add(target2.eventId);
14478
+ state.mobileInputRecoveryHeld = !1;
14479
+ } catch {
14480
+ current() && (state.mobileInputRecoveryHeld = !0, logger.warn("[AppSyncClient] Mobile inputs held: retained journal requires recovery; desktop connection remains available", { sessionId: state.sessionId }), state.onError?.(new SyncEventClientError("SYNC_INBOUND_RECOVERY_REQUIRED")));
14481
+ return;
14482
+ }
14483
+ let connection = await this.desktopSyncLiveSession(
14484
+ {
14485
+ sessionId: state.sessionId,
14486
+ sessionGenerationId: session2.sessionGenerationId
14500
14487
  },
14501
- onUpgradeRejected: () => {
14502
- current() && state.syncRegistrationRevalidatedGeneration !== generation && (state.syncRegistrationRevalidationGeneration = generation);
14503
- }
14504
- },
14505
- (event) => {
14506
- if (current() && shouldDeliverSubscribedEvent(event, !!state.receiveDesktopEvents)) return state.onEvent(event);
14507
- },
14508
- (error) => {
14509
- current() && this.handleSubscriptionError(state, error);
14510
- },
14511
- abort.signal
14512
- );
14513
- if (!current()) {
14514
- await connection.close();
14515
- return;
14516
- }
14517
- state.syncConnection = connection, state.syncSessionGenerationId = session2.sessionGenerationId, this.rememberSyncRegistration({ sessionId: state.sessionId, sessionGenerationId: session2.sessionGenerationId }), await connection.start(), current() && (state.syncRegistrationRevalidationGeneration === generation && delete state.syncRegistrationRevalidationGeneration, state.syncRegistrationRevalidatedGeneration === generation && delete state.syncRegistrationRevalidatedGeneration, this.handleSubscriptionStartAck(state));
14488
+ (event) => {
14489
+ if (current() && shouldDeliverSubscribedEvent(event, !!state.receiveDesktopEvents)) return state.onEvent(event);
14490
+ },
14491
+ () => {
14492
+ },
14493
+ abort.signal
14494
+ );
14495
+ if (!current()) {
14496
+ await connection.close();
14497
+ return;
14498
+ }
14499
+ state.syncConnection = connection;
14500
+ try {
14501
+ await connection.recoverAcceptedInputs((coordinate2) => retainedIds.add(coordinate2.eventId));
14502
+ } finally {
14503
+ await connection.close();
14504
+ }
14505
+ })().catch(() => {
14506
+ current() && (logger.warn("[AppSyncClient] Retained mobile input recovery incomplete; original journal preserved", { sessionId: state.sessionId }), state.onError?.(new SyncEventClientError("SYNC_INPUT_RECOVERY_INCOMPLETE")));
14507
+ });
14518
14508
  })().catch((error) => {
14519
14509
  current() && this.handleSubscriptionError(state, error instanceof Error ? error : new Error("Sync connection failed"));
14520
14510
  });
@@ -14530,7 +14520,9 @@ var AppSyncClient = class _AppSyncClient {
14530
14520
  receiveDesktopEvents
14531
14521
  } = state;
14532
14522
  try {
14533
- let wsUrl = this.buildRealtimeUrl(), ws = new import_ws2.default(wsUrl, ["graphql-ws"]), pendingAcks = /* @__PURE__ */ new Set([
14523
+ let wsUrl = this.buildRealtimeUrl(), owner = this.getCurrentUserId();
14524
+ this.assertSyncAccount(owner);
14525
+ let ws = new import_ws2.default(wsUrl, ["graphql-ws"]), pendingAcks = /* @__PURE__ */ new Set([
14534
14526
  subscriptionId,
14535
14527
  ...state.supervisionSubscriptionId ? [state.supervisionSubscriptionId] : []
14536
14528
  ]);
@@ -14538,6 +14530,8 @@ var AppSyncClient = class _AppSyncClient {
14538
14530
  logger.info("[AppSyncClient] WebSocket connected", { sessionId }), ws.send(JSON.stringify({ type: "connection_init" }));
14539
14531
  }), ws.on("message", (data) => {
14540
14532
  try {
14533
+ if (state.destroyed || this.activeSubscriptions.get(sessionId) !== state || state.ws !== ws) return;
14534
+ this.assertSyncAccount(owner);
14541
14535
  let message = JSON.parse(data.toString());
14542
14536
  switch (message.type) {
14543
14537
  case "connection_ack":
@@ -14553,8 +14547,8 @@ var AppSyncClient = class _AppSyncClient {
14553
14547
  supervisionEvent?.sessionId === sessionId && state.onSupervisionEvent?.(supervisionEvent);
14554
14548
  break;
14555
14549
  }
14556
- let event = message.payload?.data?.onEventCreated;
14557
- event && shouldDeliverSubscribedEvent(event, !!receiveDesktopEvents) && onEvent(event);
14550
+ let event = message.payload?.data?.onEventCreated, retainedInput = event?.source === "MOBILE" /* MOBILE */ && ["USER_PROMPT" /* USER_PROMPT */, "PROMPT_RESPONSE" /* PROMPT_RESPONSE */].includes(event.type) && (event.syncEventRevision != null || event.syncImmutableIdentityDigest != null);
14551
+ event && event.sessionId === sessionId && (event.sessionGenerationId == null || state.syncSessionGenerationId == null || event.sessionGenerationId === state.syncSessionGenerationId) && !(state.mobileInputRecoveryHeld && event.source === "MOBILE" /* MOBILE */ && ["USER_PROMPT" /* USER_PROMPT */, "PROMPT_RESPONSE" /* PROMPT_RESPONSE */].includes(event.type)) && !retainedInput && !state.compatibilityInboundIds?.has(event.eventId) && shouldDeliverSubscribedEvent(event, !!receiveDesktopEvents) && onEvent(event);
14558
14552
  break;
14559
14553
  case "ka":
14560
14554
  this.resetKeepAliveTimer(state);
@@ -58924,6 +58918,11 @@ function buildSeatbeltProfile(workdir, execPath = process.execPath, extraReadDir
58924
58918
  '(deny mach-lookup (global-name "com.apple.SecurityServer"))',
58925
58919
  '(deny mach-lookup (global-name "com.apple.securityd"))',
58926
58920
  '(deny mach-lookup (global-name "com.apple.securityd.xpc"))',
58921
+ // POSIX shared memory: grant read-data on CoreFoundation preferences shared
58922
+ // memory published by cfprefsd (apple.cfprefs.<uid>v1, apple.cfprefs.daemonv1).
58923
+ // Without this, CFPreferencesAppSynchronize fails with EPERM, breaking native
58924
+ // macOS agents like Codex CLI during configuration/preference synchronization.
58925
+ '(allow ipc-posix-shm-read-data (ipc-posix-name-prefix "apple.cfprefs."))',
58927
58926
  // The ANCESTOR DIR ENTRIES of the workdir — each as a `(literal ...)` read,
58928
58927
  // NOT a subpath (Stage-2 HIGH — the `/private/tmp` narrowing). When node runs
58929
58928
  // `node <workdir>/script.js`, `Module._findPath` → `realpathSync` `lstat`s
@@ -69407,8 +69406,8 @@ async function submitGateDecision(deps, promptEntryId, payload) {
69407
69406
  );
69408
69407
  return;
69409
69408
  }
69410
- let submitV2 = client.submitGateDecisionV2;
69411
- if (!submitV2) {
69409
+ let submitDurable = client.submitGateDecision;
69410
+ if (!submitDurable) {
69412
69411
  dispatchVisibleSubmitFailure(
69413
69412
  store,
69414
69413
  promptEntryId,
@@ -69457,9 +69456,9 @@ async function submitGateDecision(deps, promptEntryId, payload) {
69457
69456
  canonicalRequestHash: receipt2.canonicalRequestHash,
69458
69457
  decisionClaimId: null
69459
69458
  });
69460
- let result = await submitV2.call(client, request3, receipt2.canonicalRequestHash);
69459
+ let result = await submitDurable.call(client, request3, receipt2.canonicalRequestHash);
69461
69460
  if (result.decisionAttemptId !== decisionAttemptId || result.promptId !== payload.gateId)
69462
- throw new Error("submitGateDecisionV2 returned a mismatched attempt or prompt identity");
69461
+ throw new Error("submitGateDecision returned a mismatched attempt or prompt identity");
69463
69462
  if (result.acceptanceStatus === "REJECTED") {
69464
69463
  let terminal = await receiptStore.markTerminal(receipt2, {
69465
69464
  state: "REJECTED",
@@ -69702,8 +69701,8 @@ async function submitGroupGateDecision(deps, entry5, optionId, notes) {
69702
69701
  return;
69703
69702
  }
69704
69703
  if (groupEscalation.protocolVersion === 2) {
69705
- let submitV2 = deps.appsyncClient.submitGroupDecisionV2;
69706
- if (!submitV2 || groupEscalation.groupGeneration === void 0) {
69704
+ let submitDurable = deps.appsyncClient.submitGroupDecision;
69705
+ if (!submitDurable || groupEscalation.groupGeneration === void 0) {
69707
69706
  dispatchVisibleSubmitFailure(
69708
69707
  store,
69709
69708
  entry5.id,
@@ -69753,13 +69752,13 @@ async function submitGroupGateDecision(deps, entry5, optionId, notes) {
69753
69752
  canonicalRequestHash: receipt2.canonicalRequestHash,
69754
69753
  decisionClaimId: null
69755
69754
  });
69756
- let result2 = await submitV2.call(
69755
+ let result2 = await submitDurable.call(
69757
69756
  deps.appsyncClient,
69758
69757
  request3,
69759
69758
  receipt2.canonicalRequestHash
69760
69759
  );
69761
69760
  if (result2.decisionAttemptId !== decisionAttemptId || result2.promptId !== request3.promptId)
69762
- throw new Error("submitGroupDecisionV2 returned a mismatched attempt or prompt identity");
69761
+ throw new Error("submitGroupDecision returned a mismatched attempt or prompt identity");
69763
69762
  if (result2.acceptanceStatus === "REJECTED") {
69764
69763
  let terminal = await receiptStore.markTerminal(receipt2, {
69765
69764
  state: "REJECTED",
@@ -74407,7 +74406,7 @@ function createDurableResolutionAttemptHandoff(args) {
74407
74406
  }, handoff;
74408
74407
  }
74409
74408
  async function retryExactSubmission(client, receipt2) {
74410
- let result = receipt2.request.promptKind === "GATE" ? await client.submitGateDecisionV2?.(receipt2.request, receipt2.canonicalRequestHash) : await client.submitGroupDecisionV2?.(receipt2.request, receipt2.canonicalRequestHash);
74409
+ let result = receipt2.request.promptKind === "GATE" ? await client.submitGateDecision?.(receipt2.request, receipt2.canonicalRequestHash) : await client.submitGroupDecision?.(receipt2.request, receipt2.canonicalRequestHash);
74411
74410
  if (!result) throw new Error(`No ${receipt2.request.promptKind} v2 recovery transport configured`);
74412
74411
  if (result.decisionAttemptId !== receipt2.request.decisionAttemptId || result.promptId !== promptId(receipt2)) throw new Error("Decision-attempt retry returned mismatched identity");
74413
74412
  }
@@ -78929,6 +78928,14 @@ async function runOrchestrationShell(args) {
78929
78928
  // an event actually arrives (async) — never during this synchronous setup.
78930
78929
  subscribedEventDispatcher,
78931
78930
  (err) => {
78931
+ if (err instanceof SyncEventClientError && (err.code === "SYNC_INBOUND_RECOVERY_REQUIRED" || err.code === "SYNC_INPUT_RECOVERY_INCOMPLETE")) {
78932
+ logger.warn("[orchestration-shell] mobile input recovery notice; connection remains available", { code: err.code }), store.dispatch({
78933
+ type: "SHELL_ADVISORY",
78934
+ source: "shell",
78935
+ text: err.code === "SYNC_INBOUND_RECOVERY_REQUIRED" ? "Mobile input is paused for this session because its recovery journal could not be read. Desktop remains available. Messages sent during this pause are not automatically delivered later; recovery or explicit disposition is required." : "Previously accepted mobile input recovery is incomplete. Desktop and ordinary live events remain available. Retained inputs were preserved and uncertain inputs were not replayed."
78936
+ });
78937
+ return;
78938
+ }
78932
78939
  initialSubscriptionSettled || logStartupFailure("subscription", err), initialCatchUpStarted && rejectInitialSubscription(err), logger.warn("[orchestration-shell] subscribeToEvents error", {
78933
78940
  error: err.message
78934
78941
  });
@@ -79666,7 +79673,7 @@ async function runOrchestrationShell(args) {
79666
79673
  if (prepared.callStatus === "REJECTED" || prepared.authorizationState !== "READY_TO_COMMIT" || prepared.operationReceiptHash !== receiptHash2) throw new Error(`TaskGroup keep preparation failed (${prepared.rejectionCode ?? prepared.callStatus})`);
79667
79674
  if (await workspaceTerminalCoordinator.prepareGroupOutcome(taskGroupId, "kept", {
79668
79675
  filesRetained
79669
- }), (await args.appsyncClient.commitGroupDecisionV2({
79676
+ }), (await args.appsyncClient.commitGroupDecision({
79670
79677
  sessionId: resolution.sessionId,
79671
79678
  taskGroupId,
79672
79679
  decisionClaimId: resolution.decisionClaimId,
@@ -79712,7 +79719,7 @@ async function runOrchestrationShell(args) {
79712
79719
  taskGroupId,
79713
79720
  filesConflicted > 0 ? "partially_reverted" : "reverted",
79714
79721
  { filesReverted, filesConflicted }
79715
- ), (await args.appsyncClient.commitGroupDecisionV2({
79722
+ ), (await args.appsyncClient.commitGroupDecision({
79716
79723
  sessionId: resolution.sessionId,
79717
79724
  taskGroupId,
79718
79725
  decisionClaimId: resolution.decisionClaimId,