effect-agent 0.1.0-beta.96 → 0.1.0-beta.98

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/dist/{AgentRuntime-B64362Id.d.mts → AgentRuntime-BMzrJos6.d.mts} +2 -2
  2. package/dist/{AgentRuntime-Cdvqw7l_.mjs → AgentRuntime-BWOnNc0d.mjs} +78 -42
  3. package/dist/AgentRuntime-BWOnNc0d.mjs.map +1 -0
  4. package/dist/{DurableAgentRuntime-BGwGUIT-.mjs → DurableAgentRuntime-gF4YiEj2.mjs} +485 -262
  5. package/dist/DurableAgentRuntime-gF4YiEj2.mjs.map +1 -0
  6. package/dist/{DurableFailpoint-DQJet828.d.mts → DurableFailpoint-mx3-nsxU.d.mts} +3 -3
  7. package/dist/{EventSource-tCO_dAff.d.mts → EventSource-BZ73J0s5.d.mts} +3 -3
  8. package/dist/{PreparedInputAdmission-CFSddiT8.d.mts → PreparedInputAdmission-BkeI-Xvr.d.mts} +4 -4
  9. package/dist/{Records-CMByd1eD.d.mts → Records-BIiRLqlz.d.mts} +93 -101
  10. package/dist/{Records-BEz5IFUu.mjs → Records-DR1xtbXY.mjs} +36 -7
  11. package/dist/Records-DR1xtbXY.mjs.map +1 -0
  12. package/dist/{RunJournal-B_fxe57c.mjs → RunJournal-DNs3PM4K.mjs} +80 -23
  13. package/dist/RunJournal-DNs3PM4K.mjs.map +1 -0
  14. package/dist/{RunOptions-Clj8cLsp.d.mts → RunOptions-Bruk54SE.d.mts} +13 -4
  15. package/dist/{Schedule-BxCfnYr0.d.mts → Schedule-BNFlluAl.d.mts} +2 -2
  16. package/dist/{Scheduling-BW6BD_TP.mjs → Scheduling-HFH0pST1.mjs} +2 -2
  17. package/dist/{Scheduling-BW6BD_TP.mjs.map → Scheduling-HFH0pST1.mjs.map} +1 -1
  18. package/dist/{Subagent-Cbfzylz1.mjs → Subagent-C2s8PFrd.mjs} +2 -2
  19. package/dist/{Subagent-Cbfzylz1.mjs.map → Subagent-C2s8PFrd.mjs.map} +1 -1
  20. package/dist/{Subagent-Bm1dRecN.d.mts → Subagent-m7ywTCe4.d.mts} +3 -3
  21. package/dist/{Subscription-CrTIQKZR.d.mts → Subscription-BCQ3L9Zp.d.mts} +3 -3
  22. package/dist/{SubscriptionInput-BVOeFF1L.d.mts → SubscriptionInput-Cqu4_RW3.d.mts} +3 -3
  23. package/dist/{ToolReconciler-DQVaJfpE.d.mts → ToolReconciler-BmVRAHKs.d.mts} +8 -4
  24. package/dist/{agent-registration-BTa5vmQF.mjs → agent-registration-cXpB8cBU.mjs} +40 -95
  25. package/dist/agent-registration-cXpB8cBU.mjs.map +1 -0
  26. package/dist/capabilities/Commands.d.mts +1 -1
  27. package/dist/capabilities/RunHooks.d.mts +1 -1
  28. package/dist/capabilities/Subagent.d.mts +1 -1
  29. package/dist/capabilities/Subagent.mjs +1 -1
  30. package/dist/durable/ActivityStore.d.mts +1 -1
  31. package/dist/durable/ActivityStore.mjs +1 -1
  32. package/dist/durable/Admin.d.mts +1 -1
  33. package/dist/durable/Admin.mjs +12 -10
  34. package/dist/durable/Admin.mjs.map +1 -1
  35. package/dist/durable/AgentRegistration.d.mts +2 -2
  36. package/dist/durable/AgentRegistration.mjs +4 -7
  37. package/dist/durable/AgentRegistration.mjs.map +1 -1
  38. package/dist/durable/Certification.d.mts +2 -2
  39. package/dist/durable/CommittedActivity.d.mts +1 -1
  40. package/dist/durable/CommittedActivity.mjs +1 -1
  41. package/dist/durable/Digest.d.mts +1 -1
  42. package/dist/durable/Digest.mjs +1 -1
  43. package/dist/durable/DurableAgentRuntime.d.mts +1 -1
  44. package/dist/durable/DurableAgentRuntime.mjs +1 -1
  45. package/dist/durable/DurableFailpoint.d.mts +1 -1
  46. package/dist/durable/DurableFailpoint.mjs +2 -0
  47. package/dist/durable/DurableFailpoint.mjs.map +1 -1
  48. package/dist/durable/DurableFailpointTestControl.d.mts +1 -1
  49. package/dist/durable/EventSource.d.mts +1 -1
  50. package/dist/durable/EventSource.mjs +1 -1
  51. package/dist/durable/GitHubWorkflowSource.d.mts +3 -3
  52. package/dist/durable/GitHubWorkflowSource.mjs +1 -1
  53. package/dist/durable/MessageDelivery.d.mts +3 -3
  54. package/dist/durable/MessageDelivery.mjs +1 -1
  55. package/dist/durable/MessageDeliveryStoreConformance.d.mts +39 -39
  56. package/dist/durable/MessageDeliveryStoreConformance.mjs +1 -1
  57. package/dist/durable/PersistentHistory.d.mts +1 -1
  58. package/dist/durable/PersistentHistory.mjs +2 -2
  59. package/dist/durable/PreparedInputAdmission.d.mts +1 -1
  60. package/dist/durable/Records.d.mts +2 -2
  61. package/dist/durable/Records.mjs +2 -2
  62. package/dist/durable/Recovery.d.mts +1 -1
  63. package/dist/durable/Recovery.mjs +9 -9
  64. package/dist/durable/Recovery.mjs.map +1 -1
  65. package/dist/durable/RunJournal.d.mts +2 -2
  66. package/dist/durable/RunJournal.mjs +2 -2
  67. package/dist/durable/Schedule.d.mts +1 -1
  68. package/dist/durable/Schedule.mjs +1 -1
  69. package/dist/durable/ScheduleStoreConformance.d.mts +1 -1
  70. package/dist/durable/ScheduleStoreConformance.mjs +1 -1
  71. package/dist/durable/ScheduleTransition.d.mts +1 -1
  72. package/dist/durable/ScheduleTransition.mjs +1 -1
  73. package/dist/durable/Scheduling.d.mts +2 -2
  74. package/dist/durable/Scheduling.mjs +1 -1
  75. package/dist/durable/SqlStorageV2Upgrade.d.mts +2 -2
  76. package/dist/durable/SqlStorageV2Upgrade.mjs +1 -1
  77. package/dist/durable/SqlSubscriptionStore.d.mts +2 -2
  78. package/dist/durable/SqlSubscriptionStore.mjs +1 -1
  79. package/dist/durable/SubmissionLedger.d.mts +1 -1
  80. package/dist/durable/SubmissionLedger.mjs +14 -13
  81. package/dist/durable/SubmissionLedger.mjs.map +1 -1
  82. package/dist/durable/SubmissionLedgerConformance.d.mts +1 -1
  83. package/dist/durable/SubmissionLedgerConformance.mjs +9 -2
  84. package/dist/durable/SubmissionLedgerConformance.mjs.map +1 -1
  85. package/dist/durable/SubmissionStatus.d.mts +1 -1
  86. package/dist/durable/Subscription.d.mts +1 -1
  87. package/dist/durable/Subscription.mjs +1 -1
  88. package/dist/durable/SubscriptionInput.d.mts +1 -1
  89. package/dist/durable/SubscriptionInput.mjs +2 -2
  90. package/dist/durable/SubscriptionStoreConformance.d.mts +1 -1
  91. package/dist/durable/SubscriptionStoreConformance.mjs +1 -1
  92. package/dist/durable/SubscriptionTools.d.mts +3 -3
  93. package/dist/durable/SubscriptionTransition.d.mts +1 -1
  94. package/dist/durable/SubscriptionTransition.mjs +1 -1
  95. package/dist/durable/Subscriptions.d.mts +5 -5
  96. package/dist/durable/Subscriptions.mjs +1 -1
  97. package/dist/durable/ThreadContextHistory.d.mts +1 -1
  98. package/dist/durable/ThreadContextHistory.mjs +1 -1
  99. package/dist/durable/ThreadContextHistoryProjection.d.mts +1 -1
  100. package/dist/durable/ThreadContextHistoryProjection.mjs +1 -1
  101. package/dist/durable/ThreadInvariants.d.mts +4 -2
  102. package/dist/durable/ThreadInvariants.mjs +49 -3
  103. package/dist/durable/ThreadInvariants.mjs.map +1 -1
  104. package/dist/durable/ThreadProjection.d.mts +1 -1
  105. package/dist/durable/ThreadProjection.mjs +1 -1
  106. package/dist/durable/ThreadProjectionMaintenance.d.mts +1 -1
  107. package/dist/durable/ThreadStore.d.mts +1 -1
  108. package/dist/durable/ThreadStore.mjs +1 -1
  109. package/dist/durable/ThreadStoreConformance.d.mts +1 -1
  110. package/dist/durable/ThreadStoreConformance.mjs +1 -1
  111. package/dist/durable/ToolReconciler.d.mts +1 -1
  112. package/dist/durable/ToolReconciler.mjs +9 -5
  113. package/dist/durable/ToolReconciler.mjs.map +1 -1
  114. package/dist/durable/WorkerHost.d.mts +1 -1
  115. package/dist/engine/AgentRuntime.d.mts +1 -1
  116. package/dist/engine/AgentRuntime.mjs +1 -1
  117. package/dist/engine/RunOptions.d.mts +1 -1
  118. package/dist/engine/RunOptions.mjs.map +1 -1
  119. package/dist/index.d.mts +11 -11
  120. package/dist/index.mjs +6 -6
  121. package/package.json +1 -1
  122. package/src/durable/Admin.ts +20 -11
  123. package/src/durable/AgentRegistration.ts +1 -4
  124. package/src/durable/DurableAgentRuntime.ts +936 -462
  125. package/src/durable/DurableFailpoint.ts +2 -0
  126. package/src/durable/Records.ts +31 -4
  127. package/src/durable/Recovery.ts +8 -8
  128. package/src/durable/RunJournal.ts +128 -51
  129. package/src/durable/SubmissionLedger.ts +13 -12
  130. package/src/durable/SubmissionLedgerConformance.ts +13 -2
  131. package/src/durable/ThreadInvariants.ts +70 -5
  132. package/src/durable/ToolReconciler.ts +7 -3
  133. package/src/durable/internal/agent-registration.ts +77 -188
  134. package/src/durable/internal/messaging-host.ts +1 -6
  135. package/src/durable/internal/worker-host.ts +88 -116
  136. package/src/engine/RunOptions.ts +13 -3
  137. package/src/engine/internal/agent-runtime.ts +160 -106
  138. package/dist/AgentRuntime-Cdvqw7l_.mjs.map +0 -1
  139. package/dist/DurableAgentRuntime-BGwGUIT-.mjs.map +0 -1
  140. package/dist/Records-BEz5IFUu.mjs.map +0 -1
  141. package/dist/RunJournal-B_fxe57c.mjs.map +0 -1
  142. package/dist/agent-registration-BTa5vmQF.mjs.map +0 -1
@@ -105,7 +105,6 @@ import {
105
105
  } from "../WorkerHost.ts";
106
106
  import {
107
107
  definitionDigestsEqual,
108
- bindingSupports,
109
108
  resolveDefinitionBinding,
110
109
  type ResolvedBinding,
111
110
  } from "./agent-registration.ts";
@@ -381,6 +380,12 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
381
380
  };
382
381
  });
383
382
 
383
+ const currentBinding = (agentId: AgentId): ResolvedBinding | undefined => {
384
+ const matches = deps.bindings.filter((entry) => entry.agentId === agentId);
385
+
386
+ return matches.length === 1 ? matches[0] : undefined;
387
+ };
388
+
384
389
  const sourceAuthority = Effect.fn("WorkerHost.sourceAuthority")(function* (
385
390
  threadId: ThreadId,
386
391
  submissionId?: SubmissionId,
@@ -390,9 +395,7 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
390
395
 
391
396
  if (created?._tag !== "ThreadCreated") return yield* failure("start", "not-found");
392
397
 
393
- const binding = deps.bindings.find(
394
- (entry) => entry.agentId === created.agentId && bindingSupports(entry, created.definitions),
395
- );
398
+ const binding = currentBinding(created.agentId);
396
399
 
397
400
  const worker = current.records.find(
398
401
  ({ record }) => record.payload._tag === "WorkerOriginRecorded",
@@ -434,10 +437,15 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
434
437
  return yield* failure("start", "denied");
435
438
  }
436
439
 
440
+ const ownerBinding =
441
+ ownerSubmission === undefined ? undefined : currentBinding(ownerSubmission.agentId);
442
+
443
+ const selectedBinding = ownerBinding ?? binding;
444
+
437
445
  if (worker?._tag === "WorkerOriginRecorded")
438
446
  return {
439
447
  current,
440
- binding,
448
+ binding: selectedBinding,
441
449
  submission: ownerSubmission,
442
450
  policyOverride: Option.none<AgentPolicy>(),
443
451
  policy: worker.origin.policy,
@@ -456,7 +464,7 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
456
464
 
457
465
  return {
458
466
  current,
459
- binding,
467
+ binding: selectedBinding,
460
468
  submission: ownerSubmission,
461
469
  policyOverride: Option.none<AgentPolicy>(),
462
470
  policy: attached.policy,
@@ -467,17 +475,6 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
467
475
  };
468
476
  }
469
477
 
470
- const ownerBinding =
471
- ownerSubmission === undefined
472
- ? undefined
473
- : deps.bindings.find(
474
- (entry) =>
475
- entry.agentId === ownerSubmission.agentId &&
476
- bindingSupports(entry, ownerSubmission.agentDigests),
477
- );
478
-
479
- const selectedBinding = ownerBinding ?? binding;
480
-
481
478
  const changedRootAgent =
482
479
  ownerSubmission !== undefined && ownerSubmission.agentId !== created.agentId;
483
480
 
@@ -497,7 +494,9 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
497
494
  return yield* failure("start", "declaration-unavailable");
498
495
 
499
496
  const effectiveBinding =
500
- Option.isSome(selected) || changedRootAgent ? selectedBinding : binding;
497
+ Option.isSome(selected) || changedRootAgent || binding === undefined
498
+ ? selectedBinding
499
+ : binding;
501
500
 
502
501
  if (effectiveBinding === undefined) return yield* failure("start", "declaration-unavailable");
503
502
 
@@ -718,6 +717,7 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
718
717
  inputDigest: Digest,
719
718
  input: PersistedJson,
720
719
  principal: Principal,
720
+ retainedFrameworkInput: boolean,
721
721
  ): Effect.fn.Return<void, WorkerError> {
722
722
  const origin = admission.origin;
723
723
  const id = `worker-input:${admission.messageId}`;
@@ -763,17 +763,16 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
763
763
 
764
764
  const sourceBinding = source.binding;
765
765
 
766
- const targetBinding = deps.bindings.find(
767
- (entry) =>
768
- entry.agentId === origin.worker.targetAgentId &&
769
- bindingSupports(entry, origin.targetDigests),
770
- );
766
+ const targetBinding = currentBinding(origin.worker.targetAgentId);
771
767
 
772
768
  if (sourceBinding === undefined || targetBinding === undefined)
773
769
  return yield* failure("start", "declaration-unavailable");
774
- yield* Schema.decodeEffect(Schema.toEncoded(targetBinding.definition.input))(input).pipe(
775
- Effect.mapError(() => failure("start", "corrupt")),
776
- );
770
+ // Standard reports and updates retain the owner's original input bytes. Their
771
+ // framework message carries the new information independently of the current input codec.
772
+ if (!retainedFrameworkInput)
773
+ yield* Schema.decodeEffect(Schema.toEncoded(targetBinding.definition.input))(input).pipe(
774
+ Effect.mapError(() => failure("start", "corrupt")),
775
+ );
777
776
 
778
777
  const targetRequest = {
779
778
  definition: targetBinding.definition,
@@ -1024,7 +1023,11 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
1024
1023
  admission.deliveryPrincipal !== options.principal)
1025
1024
  )
1026
1025
  return yield* failure("start", "worker-mismatch");
1027
- yield* reservation(admission, inputDigest, input, options.principal);
1026
+ const retainedFrameworkInput = Schema.is(FrameworkMessage)(options.messageAdmission);
1027
+
1028
+ if (retainedFrameworkInput && admission.reportKind !== "update")
1029
+ yield* validateCompletion(options.messageAdmission, options, agentId, inputDigest);
1030
+ yield* reservation(admission, inputDigest, input, options.principal, retainedFrameworkInput);
1028
1031
 
1029
1032
  return admission;
1030
1033
  });
@@ -1038,17 +1041,26 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
1038
1041
  if (update.threadId !== submission.threadId || update.agentId !== origin.worker.targetAgentId)
1039
1042
  return yield* failure("followUp", "worker-mismatch");
1040
1043
 
1041
- const sourceBinding = deps.bindings.find(
1042
- (entry) =>
1043
- entry.agentId === origin.source.agentId && bindingSupports(entry, intent.sourceDigests),
1044
+ const sourceHistory = yield* read(origin.source.threadId, "followUp");
1045
+
1046
+ const first = requests(sourceHistory.records).find(
1047
+ (row) => row.admission.messageId === origin.firstMessageId,
1044
1048
  );
1045
1049
 
1046
- const targetBinding = deps.bindings.find(
1047
- (entry) =>
1048
- entry.agentId === origin.worker.targetAgentId &&
1049
- bindingSupports(entry, origin.targetDigests),
1050
+ if (first === undefined || !sameOrigin(first.admission.origin, origin))
1051
+ return yield* failure("followUp", "corrupt");
1052
+
1053
+ const source = yield* sourceAuthority(
1054
+ origin.source.threadId,
1055
+ first.admission.sourceSubmissionId,
1050
1056
  );
1051
1057
 
1058
+ if (source.binding === undefined || source.submission === undefined)
1059
+ return yield* failure("followUp", "declaration-unavailable");
1060
+
1061
+ const sourceBinding = currentBinding(origin.source.agentId);
1062
+ const targetBinding = currentBinding(origin.worker.targetAgentId);
1063
+
1052
1064
  const reports =
1053
1065
  sourceBinding?.reporting?.filter(
1054
1066
  (entry) => entry.delegationId === origin.worker.delegationId,
@@ -1063,26 +1075,6 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
1063
1075
  !definitionDigestsEqual(submission.agentDigests, origin.targetDigests)
1064
1076
  )
1065
1077
  return yield* failure("followUp", "declaration-unavailable");
1066
- const sourceHistory = yield* read(origin.source.threadId, "followUp");
1067
-
1068
- const first = requests(sourceHistory.records).find(
1069
- (row) => row.admission.messageId === origin.firstMessageId,
1070
- );
1071
-
1072
- if (first === undefined || !sameOrigin(first.admission.origin, origin))
1073
- return yield* failure("followUp", "corrupt");
1074
-
1075
- const source = yield* sourceAuthority(
1076
- origin.source.threadId,
1077
- first.admission.sourceSubmissionId,
1078
- );
1079
-
1080
- if (
1081
- source.binding === undefined ||
1082
- source.submission === undefined ||
1083
- !bindingSupports(source.binding, intent.sourceDigests)
1084
- )
1085
- return yield* failure("followUp", "declaration-unavailable");
1086
1078
 
1087
1079
  const recorded = source.current.records.find(
1088
1080
  ({ record }) => record.payload._tag === "WorkerOriginRecorded",
@@ -1101,14 +1093,7 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
1101
1093
  );
1102
1094
 
1103
1095
  if (now >= deadlineAtMillis) return yield* failure("followUp", "denied");
1104
- const sourceSubmission = source.submission;
1105
-
1106
- const input = yield* Schema.decodeEffect(Schema.toEncoded(sourceBinding.definition.input))(
1107
- source.submission.inputPayload,
1108
- ).pipe(
1109
- Effect.flatMap(() => Schema.decodeEffect(PersistedJson)(sourceSubmission.inputPayload)),
1110
- Effect.mapError(() => failure("followUp", "corrupt")),
1111
- );
1096
+ const input = source.submission.inputPayload;
1112
1097
 
1113
1098
  let workerAdmission: WorkerAdmission | undefined;
1114
1099
  let principal = submission.principal;
@@ -1229,39 +1214,6 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
1229
1214
  const refused = (reason: WorkerReportRefused["reason"]) =>
1230
1215
  WorkerReportRefused.make({ runId, messageId, reason });
1231
1216
 
1232
- const sourceBinding = deps.bindings.find(
1233
- (entry) =>
1234
- entry.agentId === origin.source.agentId && bindingSupports(entry, intent.sourceDigests),
1235
- );
1236
-
1237
- const targetBinding = deps.bindings.find(
1238
- (entry) =>
1239
- entry.agentId === origin.worker.targetAgentId &&
1240
- bindingSupports(entry, origin.targetDigests),
1241
- );
1242
-
1243
- const reports =
1244
- sourceBinding?.reporting?.filter(
1245
- (entry) => entry.delegationId === origin.worker.delegationId,
1246
- ) ?? [];
1247
-
1248
- const descriptor = reports[0];
1249
-
1250
- if (
1251
- sourceBinding === undefined ||
1252
- targetBinding === undefined ||
1253
- descriptor === undefined ||
1254
- reports.length !== 1 ||
1255
- !Object.is(descriptor.target, targetBinding.definition) ||
1256
- (descriptor.mode !== "standard" &&
1257
- !Object.is(descriptor.input, sourceBinding.definition.input)) ||
1258
- descriptor.mode !== intent.mode ||
1259
- descriptor.destination?.delegationId !== intent.destinationDelegationId ||
1260
- (descriptor.destination !== undefined &&
1261
- !Object.is(descriptor.destination.target, sourceBinding.definition))
1262
- )
1263
- return refused("declaration-unavailable");
1264
-
1265
1217
  const selected = yield* deps.ledger
1266
1218
  .lookup(SubmissionLookupById.make({ submissionId: host.submissionId }))
1267
1219
  .pipe(Effect.mapError(storageFailure("inspect")));
@@ -1293,7 +1245,31 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
1293
1245
  firstInput.admission.sourceSubmissionId,
1294
1246
  );
1295
1247
 
1296
- if (source.binding === undefined || !bindingSupports(source.binding, intent.sourceDigests))
1248
+ if (source.binding === undefined) return refused("declaration-unavailable");
1249
+
1250
+ const sourceBinding = currentBinding(origin.source.agentId);
1251
+ const targetBinding = currentBinding(origin.worker.targetAgentId);
1252
+
1253
+ const reports =
1254
+ sourceBinding?.reporting?.filter(
1255
+ (entry) => entry.delegationId === origin.worker.delegationId,
1256
+ ) ?? [];
1257
+
1258
+ const descriptor = reports[0];
1259
+
1260
+ if (
1261
+ sourceBinding === undefined ||
1262
+ targetBinding === undefined ||
1263
+ descriptor === undefined ||
1264
+ reports.length !== 1 ||
1265
+ !Object.is(descriptor.target, targetBinding.definition) ||
1266
+ (descriptor.mode !== "standard" &&
1267
+ !Object.is(descriptor.input, sourceBinding.definition.input)) ||
1268
+ descriptor.mode !== intent.mode ||
1269
+ descriptor.destination?.delegationId !== intent.destinationDelegationId ||
1270
+ (descriptor.destination !== undefined &&
1271
+ !Object.is(descriptor.destination.target, sourceBinding.definition))
1272
+ )
1297
1273
  return refused("declaration-unavailable");
1298
1274
 
1299
1275
  const sourceOriginRecord = source.current.records.find(
@@ -1388,12 +1364,13 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
1388
1364
  ? source.submission?.inputPayload
1389
1365
  : projection.value.encodedInput;
1390
1366
 
1391
- const validated = yield* Schema.decodeEffect(
1392
- Schema.toEncoded(sourceBinding.definition.input),
1393
- )(reportInput).pipe(
1394
- Effect.flatMap(() => Schema.decodeUnknownEffect(PersistedJson)(reportInput)),
1395
- Effect.option,
1396
- );
1367
+ const validated = yield* (
1368
+ descriptor.mode === "standard"
1369
+ ? Schema.decodeUnknownEffect(PersistedJson)(reportInput)
1370
+ : Schema.decodeEffect(Schema.toEncoded(sourceBinding.definition.input))(reportInput).pipe(
1371
+ Effect.flatMap(() => Schema.decodeUnknownEffect(PersistedJson)(reportInput)),
1372
+ )
1373
+ ).pipe(Effect.option);
1397
1374
 
1398
1375
  if (Option.isNone(validated)) return refused("input");
1399
1376
  const input = validated.value;
@@ -1680,7 +1657,7 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
1680
1657
  target: Agent.AnyDefinition,
1681
1658
  operation: WorkerError["operation"],
1682
1659
  ) {
1683
- const resolved = yield* binding(target, operation);
1660
+ yield* binding(target, operation);
1684
1661
 
1685
1662
  if (worker.targetAgentId !== target.id) return yield* failure(operation, "worker-mismatch");
1686
1663
  const source = yield* read(context.source.threadId, operation);
@@ -1690,10 +1667,7 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
1690
1667
  )?.admission.origin;
1691
1668
 
1692
1669
  if (origin === undefined) return yield* failure(operation, "not-found");
1693
- if (
1694
- origin.worker.delegationId !== worker.delegationId ||
1695
- !bindingSupports(resolved, origin.targetDigests)
1696
- )
1670
+ if (origin.worker.delegationId !== worker.delegationId)
1697
1671
  return yield* failure(operation, "worker-mismatch");
1698
1672
 
1699
1673
  return origin;
@@ -2055,7 +2029,7 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
2055
2029
  threadId: Schema.decodeSync(ThreadId)(messageId),
2056
2030
  },
2057
2031
  source: existing?.envelope.workerAdmission?.origin.source ?? context.source,
2058
- targetDigests: resolved.digests,
2032
+ targetDigests: previousOrigin?.targetDigests ?? resolved.digests,
2059
2033
  policy: request.policy,
2060
2034
  budget: request.budget,
2061
2035
  ...(request.budgetScope === undefined ? {} : { budgetScope: request.budgetScope }),
@@ -2398,9 +2372,12 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
2398
2372
 
2399
2373
  if (created?._tag !== "ThreadCreated") return yield* failure("context", "not-found");
2400
2374
 
2401
- const resolved = deps.bindings.find(
2402
- (entry) => entry.agentId === created.agentId && bindingSupports(entry, created.definitions),
2403
- );
2375
+ const selected =
2376
+ request.sourceSubmissionId === undefined
2377
+ ? undefined
2378
+ : yield* sourceAuthority(sourceThreadId, request.sourceSubmissionId);
2379
+
2380
+ const resolved = selected === undefined ? currentBinding(created.agentId) : selected.binding;
2404
2381
 
2405
2382
  if (resolved === undefined) return yield* failure("context", "declaration-unavailable");
2406
2383
 
@@ -2419,11 +2396,6 @@ export const makeWorkerRuntime = Effect.fn("WorkerHost.make")(function* (
2419
2396
  ? attached
2420
2397
  : undefined;
2421
2398
 
2422
- const selected =
2423
- request.sourceSubmissionId === undefined
2424
- ? undefined
2425
- : yield* sourceAuthority(sourceThreadId, request.sourceSubmissionId);
2426
-
2427
2399
  return facet(
2428
2400
  {
2429
2401
  source: {
@@ -611,9 +611,9 @@ export interface RunDurabilityHook<Error = never, Requirements = never> {
611
611
  /**
612
612
  * `DefinitionDigests`-shaped digests of one child Agent Binding in plain
613
613
  * string form. The durable coordinator's thread-owned digest Schema never
614
- * crosses inward: the coordinator resolves these digests from the exact
615
- * registered target and stores and verifies them
616
- * byte-for-byte (SUB-023 exact-digest binding resolution).
614
+ * crosses inward: the coordinator captures these digests from the admitted target
615
+ * and verifies them byte-for-byte as immutable provenance. Current executable
616
+ * selection uses the stable Agent identity, independently of historical definitions.
617
617
  */
618
618
  export interface RunSubagentDigests {
619
619
  readonly agent: string;
@@ -829,6 +829,8 @@ export type RunResumeUsage = typeof RunResumeUsageSchema.Type;
829
829
  * proceeds through the normal continuation.
830
830
  */
831
831
  export interface RunTurnResume {
832
+ /** A successful settled call whose original operation contract still supports completion projection. */
833
+ readonly settledCompletion?: ToolCallId | undefined;
832
834
  /** Canonical rejection evidence, matched to the exact call; never permits handler execution. */
833
835
  readonly toolParameterRejections?: ReadonlyArray<ToolParameterRejection> | undefined;
834
836
  readonly toolExposure?: Snapshot | undefined;
@@ -919,6 +921,14 @@ export interface RunOptions<HookError = never, HookRequirements = never> {
919
921
  /** Host-validated worker message; application input still supplies instructions and policy context. */
920
922
  readonly frameworkMessage?: FrameworkMessage;
921
923
 
924
+ /**
925
+ * Original admitted JSON for a durable continuation or verified framework message. Static
926
+ * instructions can resume without decoding a future input Schema; input-dependent instructions
927
+ * still require that Schema. The original value remains the policy input, and a saved prompt
928
+ * is restored through `context` instead of rerendering the application's input prompt.
929
+ */
930
+ readonly retainedInput?: Schema.Json | undefined;
931
+
922
932
  /** Initial or canonically restored run-scoped native selection. */
923
933
  readonly toolSelection?: Selection | undefined;
924
934
  /**