@yielded/agent 0.1.0-beta.173 → 0.1.0-beta.175

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 (266) hide show
  1. package/dist/{Admin-BX9ns28E.d.mts → Admin-Qa3I1oA5.d.mts} +61 -21
  2. package/dist/{Agent-9aBoIi74.d.mts → Agent-B39jRnFv.d.mts} +2 -2
  3. package/dist/{Agent-0WvBWWbM.mjs → Agent-BiRbr73L.mjs} +7 -6
  4. package/dist/Agent-BiRbr73L.mjs.map +1 -0
  5. package/dist/{AgentRuntime-BfP14534.d.mts → AgentRuntime-CHDyRbSf.d.mts} +12 -12
  6. package/dist/{AgentRuntime-CQ-qcETl.mjs → AgentRuntime-DaDKMasp.mjs} +290 -273
  7. package/dist/AgentRuntime-DaDKMasp.mjs.map +1 -0
  8. package/dist/{Digest-DCuPlhNk.mjs → Digest-C3EODOee.mjs} +42 -15
  9. package/dist/Digest-C3EODOee.mjs.map +1 -0
  10. package/dist/{DurableAgentRuntime-BAmSkWYr.mjs → DurableAgentRuntime-CPlw5_7e.mjs} +1557 -1458
  11. package/dist/DurableAgentRuntime-CPlw5_7e.mjs.map +1 -0
  12. package/dist/{EventSource-BwliwQz9.d.mts → EventSource-BTu68yDW.d.mts} +2 -2
  13. package/dist/InMemory.d.mts +2 -2
  14. package/dist/{MessageDelivery-B943ebI_.d.mts → MessageDelivery-DjAZJ4Fd.d.mts} +42 -42
  15. package/dist/{Messaging-C_6OOg_s.d.mts → Messaging-SVu6rWV8.d.mts} +12 -6
  16. package/dist/{MessagingHost-B8oKM7AC.d.mts → MessagingHost-C6SOAcoG.d.mts} +2 -2
  17. package/dist/{MessagingHost-CRUK4JBi.mjs → MessagingHost-CZCyrnvJ.mjs} +27 -26
  18. package/dist/MessagingHost-CZCyrnvJ.mjs.map +1 -0
  19. package/dist/{Output-Dsx6k52t.d.mts → Output-CRamN1Fy.d.mts} +2 -2
  20. package/dist/{PreparedInputAdmission-CxSJSiTl.d.mts → PreparedInputAdmission-wgY4JMZY.d.mts} +3 -3
  21. package/dist/{Records-BiuJDWNe.mjs → Records-DzL4Kbtw.mjs} +2 -2
  22. package/dist/{Records-BiuJDWNe.mjs.map → Records-DzL4Kbtw.mjs.map} +1 -1
  23. package/dist/{RunContinuation-FHM7XPjq.d.mts → RunContinuation-3jB5pULC.d.mts} +13 -7
  24. package/dist/{RunContinuation-DHYNAQFi.mjs → RunContinuation-BiyKJK32.mjs} +173 -82
  25. package/dist/RunContinuation-BiyKJK32.mjs.map +1 -0
  26. package/dist/{RunJournal-kfKVxJj7.mjs → RunJournal-CPMKcfd0.mjs} +106 -73
  27. package/dist/RunJournal-CPMKcfd0.mjs.map +1 -0
  28. package/dist/{RunOptions-D8zxFIrZ.d.mts → RunOptions-Be77lKVZ.d.mts} +2 -2
  29. package/dist/{RunStorage-uqPxps09.mjs → RunStorage-CzutHJBE.mjs} +10 -6
  30. package/dist/RunStorage-CzutHJBE.mjs.map +1 -0
  31. package/dist/{Scheduling-CVyfXlBR.mjs → Scheduling-07_dsGED.mjs} +12 -12
  32. package/dist/Scheduling-07_dsGED.mjs.map +1 -0
  33. package/dist/{Subagent-vpffemql.mjs → Subagent-CexndZSp.mjs} +53 -40
  34. package/dist/Subagent-CexndZSp.mjs.map +1 -0
  35. package/dist/{Subagent-E6tvd7-k.d.mts → Subagent-xhN_aD1r.d.mts} +20 -9
  36. package/dist/{SubagentHost-B6w2m-SI.d.mts → SubagentHost-D1xBgn9g.d.mts} +2 -2
  37. package/dist/{Subscription-DONig54Q.d.mts → Subscription-DmIHlOJK.d.mts} +2 -2
  38. package/dist/{SubscriptionInput-mJIRxWJM.d.mts → SubscriptionInput-DgcQhvbe.d.mts} +2 -2
  39. package/dist/{Thread-dk-QiNml.d.mts → Thread-DzdJAY4J.d.mts} +4 -3
  40. package/dist/{ThreadHistory-ByxS8HU1.d.mts → ThreadHistory-KPPBJLJb.d.mts} +12 -2
  41. package/dist/{ThreadImport-DckUMEqJ.mjs → ThreadImport-CjlG57vH.mjs} +9 -9
  42. package/dist/ThreadImport-CjlG57vH.mjs.map +1 -0
  43. package/dist/{ThreadImport-DpHxjBrA.d.mts → ThreadImport-DP-vOk2F.d.mts} +5 -5
  44. package/dist/{ThreadStore-CEekRa80.mjs → ThreadStore-EuUilthA.mjs} +162 -85
  45. package/dist/ThreadStore-EuUilthA.mjs.map +1 -0
  46. package/dist/{ThreadTransfer-B4gTQLIl.mjs → ThreadTransfer-DB_zsrtJ.mjs} +4 -4
  47. package/dist/{ThreadTransfer-B4gTQLIl.mjs.map → ThreadTransfer-DB_zsrtJ.mjs.map} +1 -1
  48. package/dist/{WorkerAdmission-DFVbbVh2.mjs → WorkerAdmission-eBeXt_mu.mjs} +5 -5
  49. package/dist/{WorkerAdmission-DFVbbVh2.mjs.map → WorkerAdmission-eBeXt_mu.mjs.map} +1 -1
  50. package/dist/{agent-registration-ByMZ_cK5.mjs → agent-registration-a6QYaG3h.mjs} +70 -57
  51. package/dist/agent-registration-a6QYaG3h.mjs.map +1 -0
  52. package/dist/capabilities/Approval.mjs +2 -2
  53. package/dist/capabilities/Approval.mjs.map +1 -1
  54. package/dist/capabilities/BrowserUse.d.mts +102 -1867
  55. package/dist/capabilities/BrowserUse.mjs +74 -798
  56. package/dist/capabilities/BrowserUse.mjs.map +1 -1
  57. package/dist/capabilities/Budget.mjs +3 -1
  58. package/dist/capabilities/Budget.mjs.map +1 -1
  59. package/dist/capabilities/CodeMode.d.mts +1 -1
  60. package/dist/capabilities/CodeMode.mjs +16 -9
  61. package/dist/capabilities/CodeMode.mjs.map +1 -1
  62. package/dist/capabilities/Commands.d.mts +1 -1
  63. package/dist/capabilities/McpClient.mjs +1 -1
  64. package/dist/capabilities/McpClient.mjs.map +1 -1
  65. package/dist/capabilities/Messaging.d.mts +1 -1
  66. package/dist/capabilities/Messaging.mjs +5 -5
  67. package/dist/capabilities/Messaging.mjs.map +1 -1
  68. package/dist/capabilities/ModelContext.d.mts +1 -1
  69. package/dist/capabilities/ModelContext.mjs +7 -5
  70. package/dist/capabilities/ModelContext.mjs.map +1 -1
  71. package/dist/capabilities/Redaction.mjs +49 -19
  72. package/dist/capabilities/Redaction.mjs.map +1 -1
  73. package/dist/capabilities/RunHooks.d.mts +2 -2
  74. package/dist/capabilities/RunHooks.mjs +1 -1
  75. package/dist/capabilities/RunHooks.mjs.map +1 -1
  76. package/dist/capabilities/Subagent.d.mts +1 -1
  77. package/dist/capabilities/Subagent.mjs +1 -1
  78. package/dist/capabilities/SubagentReservations.mjs +3 -1
  79. package/dist/capabilities/SubagentReservations.mjs.map +1 -1
  80. package/dist/capabilities/WebCapture.mjs.map +1 -1
  81. package/dist/capabilities/WebSearch.mjs +7 -7
  82. package/dist/capabilities/WebSearch.mjs.map +1 -1
  83. package/dist/core/Agent.d.mts +1 -1
  84. package/dist/core/Agent.mjs +1 -1
  85. package/dist/core/AgentUpdates.mjs +8 -8
  86. package/dist/core/AgentUpdates.mjs.map +1 -1
  87. package/dist/core/Thread.d.mts +2 -2
  88. package/dist/core/Thread.mjs +6 -4
  89. package/dist/core/Thread.mjs.map +1 -1
  90. package/dist/core/Usage.mjs +2 -2
  91. package/dist/core/Usage.mjs.map +1 -1
  92. package/dist/durable/ActivityStore.mjs +1 -1
  93. package/dist/durable/Admin.d.mts +1 -1
  94. package/dist/durable/Admin.mjs +1 -1
  95. package/dist/durable/AgentRegistration.d.mts +1 -1
  96. package/dist/durable/AgentRegistration.mjs +1 -1
  97. package/dist/durable/Certification.d.mts +1 -1
  98. package/dist/durable/CommittedActivity.d.mts +1 -1
  99. package/dist/durable/CommittedActivity.mjs +3 -3
  100. package/dist/durable/Digest.mjs +1 -1
  101. package/dist/durable/DurableAgentRuntime.d.mts +1 -1
  102. package/dist/durable/DurableAgentRuntime.mjs +2 -2
  103. package/dist/durable/EventSource.d.mts +1 -1
  104. package/dist/durable/EventSource.mjs +7 -7
  105. package/dist/durable/EventSource.mjs.map +1 -1
  106. package/dist/durable/GitHubWorkflowSource.d.mts +3 -3
  107. package/dist/durable/LifecyclePublication.d.mts +1 -1
  108. package/dist/durable/LifecyclePublication.mjs +2 -2
  109. package/dist/durable/MessageDelivery.d.mts +1 -1
  110. package/dist/durable/MessageDelivery.mjs +2 -2
  111. package/dist/durable/MessageDeliveryStoreConformance.d.mts +40 -40
  112. package/dist/durable/MessageDeliveryStoreConformance.mjs +2 -2
  113. package/dist/durable/PersistentHistory.d.mts +2 -2
  114. package/dist/durable/PersistentHistory.mjs +4 -4
  115. package/dist/durable/PreparedInputAdmission.d.mts +1 -1
  116. package/dist/durable/RecordFormat.mjs +3 -3
  117. package/dist/durable/RecordFormat.mjs.map +1 -1
  118. package/dist/durable/Records.mjs +1 -1
  119. package/dist/durable/Recovery.d.mts +1 -1
  120. package/dist/durable/Recovery.mjs +1 -1
  121. package/dist/durable/RunContinuation.d.mts +2 -2
  122. package/dist/durable/RunContinuation.mjs +3 -3
  123. package/dist/durable/RunJournal.d.mts +2 -2
  124. package/dist/durable/RunJournal.mjs +2 -2
  125. package/dist/durable/RunStorage.d.mts +1 -1
  126. package/dist/durable/RunStorage.mjs +1 -1
  127. package/dist/durable/Schedule.mjs +1 -1
  128. package/dist/durable/ScheduleStoreConformance.mjs +1 -1
  129. package/dist/durable/ScheduleTransition.mjs +1 -1
  130. package/dist/durable/Scheduling.d.mts +1 -1
  131. package/dist/durable/Scheduling.mjs +1 -1
  132. package/dist/durable/SettlementPublisher.d.mts +1 -1
  133. package/dist/durable/SettlementPublisher.mjs +3 -3
  134. package/dist/durable/SqlMemoryStore.mjs +5 -3
  135. package/dist/durable/SqlMemoryStore.mjs.map +1 -1
  136. package/dist/durable/SubmissionLedger.d.mts +1 -1
  137. package/dist/durable/SubmissionLedger.mjs +11 -3
  138. package/dist/durable/SubmissionLedger.mjs.map +1 -1
  139. package/dist/durable/SubmissionLedgerConformance.d.mts +1 -1
  140. package/dist/durable/SubmissionLedgerConformance.mjs +6 -6
  141. package/dist/durable/SubmissionStatus.d.mts +1 -1
  142. package/dist/durable/Subscription.d.mts +1 -1
  143. package/dist/durable/Subscription.mjs +2 -2
  144. package/dist/durable/SubscriptionInput.d.mts +1 -1
  145. package/dist/durable/SubscriptionInput.mjs +4 -4
  146. package/dist/durable/SubscriptionInput.mjs.map +1 -1
  147. package/dist/durable/SubscriptionStoreConformance.d.mts +1 -1
  148. package/dist/durable/SubscriptionStoreConformance.mjs +3 -3
  149. package/dist/durable/SubscriptionStoreConformance.mjs.map +1 -1
  150. package/dist/durable/SubscriptionTools.d.mts +2 -2
  151. package/dist/durable/SubscriptionTransition.d.mts +1 -1
  152. package/dist/durable/SubscriptionTransition.mjs +1 -1
  153. package/dist/durable/Subscriptions.d.mts +5 -5
  154. package/dist/durable/Subscriptions.mjs +3 -3
  155. package/dist/durable/Subscriptions.mjs.map +1 -1
  156. package/dist/durable/ThreadArchiveRange.d.mts +1 -1
  157. package/dist/durable/ThreadArchiveRange.mjs +1 -1
  158. package/dist/durable/ThreadContextHistory.d.mts +1 -1
  159. package/dist/durable/ThreadContextHistory.mjs +2 -2
  160. package/dist/durable/ThreadContextHistoryProjection.mjs +1 -1
  161. package/dist/durable/ThreadImport.d.mts +1 -1
  162. package/dist/durable/ThreadImport.mjs +1 -1
  163. package/dist/durable/ThreadInvariants.d.mts +3 -3
  164. package/dist/durable/ThreadInvariants.mjs +5 -5
  165. package/dist/durable/ThreadInvariants.mjs.map +1 -1
  166. package/dist/durable/ThreadProjection.mjs +1 -1
  167. package/dist/durable/ThreadProjectionMaintenance.d.mts +1 -1
  168. package/dist/durable/ThreadReader.d.mts +1 -1
  169. package/dist/durable/ThreadReader.mjs +1 -1
  170. package/dist/durable/ThreadStore.d.mts +1 -1
  171. package/dist/durable/ThreadStore.mjs +2 -2
  172. package/dist/durable/ThreadStoreConformance.d.mts +1 -1
  173. package/dist/durable/ThreadStoreConformance.mjs +4 -4
  174. package/dist/durable/ThreadTransfer.d.mts +1 -1
  175. package/dist/durable/ThreadTransfer.mjs +1 -1
  176. package/dist/durable/ThreadWork.d.mts +2 -2
  177. package/dist/durable/ThreadWork.mjs +12 -6
  178. package/dist/durable/ThreadWork.mjs.map +1 -1
  179. package/dist/durable/ToolReconciler.mjs +1 -1
  180. package/dist/durable/WakeScheduler.mjs +23 -39
  181. package/dist/durable/WakeScheduler.mjs.map +1 -1
  182. package/dist/durable/WorkerAdmission.d.mts +1 -1
  183. package/dist/durable/WorkerAdmission.mjs +1 -1
  184. package/dist/durable/WorkerHost.d.mts +2 -2
  185. package/dist/engine/AgentRuntime.d.mts +1 -1
  186. package/dist/engine/AgentRuntime.mjs +1 -1
  187. package/dist/engine/MessagingHost.d.mts +1 -1
  188. package/dist/engine/MessagingHost.mjs +1 -1
  189. package/dist/engine/Output.d.mts +1 -1
  190. package/dist/engine/Output.mjs +1 -1
  191. package/dist/engine/RunOptions.d.mts +1 -1
  192. package/dist/engine/SubagentHost.d.mts +1 -1
  193. package/dist/engine/ThreadHistory.d.mts +1 -1
  194. package/dist/engine/ThreadHistory.mjs +3 -2
  195. package/dist/engine/ThreadHistory.mjs.map +1 -1
  196. package/dist/index.d.mts +21 -21
  197. package/dist/index.mjs +16 -16
  198. package/dist/{output-contract-CMIhu4Cw.mjs → output-contract-DCnLYCdp.mjs} +12 -15
  199. package/dist/{output-contract-CMIhu4Cw.mjs.map → output-contract-DCnLYCdp.mjs.map} +1 -1
  200. package/dist/{run-context-reader-OcsZr4bk.d.mts → run-context-reader-DVhJZ1Qe.d.mts} +2 -2
  201. package/package.json +1 -1
  202. package/src/capabilities/Approval.ts +58 -60
  203. package/src/capabilities/BrowserUse.ts +89 -944
  204. package/src/capabilities/Budget.ts +8 -1
  205. package/src/capabilities/CodeMode.ts +57 -33
  206. package/src/capabilities/McpClient.ts +2 -2
  207. package/src/capabilities/Messaging.ts +51 -55
  208. package/src/capabilities/ModelContext.ts +5 -2
  209. package/src/capabilities/Redaction.ts +64 -34
  210. package/src/capabilities/RunHooks.ts +52 -55
  211. package/src/capabilities/Subagent.ts +33 -33
  212. package/src/capabilities/SubagentReservations.ts +9 -1
  213. package/src/capabilities/WebCapture.ts +6 -0
  214. package/src/capabilities/WebSearch.ts +10 -7
  215. package/src/capabilities/internal/subagent-background.ts +202 -158
  216. package/src/core/Agent.ts +11 -6
  217. package/src/core/AgentUpdates.ts +8 -8
  218. package/src/core/Thread.ts +142 -146
  219. package/src/core/Usage.ts +7 -8
  220. package/src/core/internal/agent-updates.ts +1 -0
  221. package/src/durable/DurableAgentRuntime.ts +1024 -829
  222. package/src/durable/EventSource.ts +15 -9
  223. package/src/durable/RecordFormat.ts +5 -3
  224. package/src/durable/RunContinuation.ts +316 -113
  225. package/src/durable/RunJournal.ts +106 -114
  226. package/src/durable/RunStorage.ts +129 -124
  227. package/src/durable/Scheduling.ts +639 -651
  228. package/src/durable/SqlMemoryStore.ts +8 -6
  229. package/src/durable/SubmissionLedger.ts +11 -0
  230. package/src/durable/SubscriptionInput.ts +5 -3
  231. package/src/durable/SubscriptionStoreConformance.ts +23 -23
  232. package/src/durable/Subscriptions.ts +18 -19
  233. package/src/durable/ThreadImport.ts +18 -19
  234. package/src/durable/ThreadInvariants.ts +2 -1
  235. package/src/durable/ThreadStore.ts +217 -111
  236. package/src/durable/ThreadWork.ts +11 -2
  237. package/src/durable/WakeScheduler.ts +34 -66
  238. package/src/durable/internal/StorageOwner.ts +10 -4
  239. package/src/durable/internal/agent-registration.ts +96 -89
  240. package/src/durable/internal/canonical-json.ts +61 -20
  241. package/src/durable/internal/prompt-history-cache.ts +13 -4
  242. package/src/durable/internal/record-encoding.ts +120 -64
  243. package/src/durable/internal/schedule-time.ts +6 -6
  244. package/src/durable/internal/usage-totals.ts +35 -0
  245. package/src/durable/internal/worker-host.ts +69 -74
  246. package/src/engine/MessagingHost.ts +4 -2
  247. package/src/engine/ThreadHistory.ts +47 -48
  248. package/src/engine/internal/agent-runtime.ts +1298 -1217
  249. package/src/engine/internal/output-contract.ts +15 -15
  250. package/src/engine/internal/primitive-delta.ts +2 -3
  251. package/src/engine/internal/provisional-text.ts +12 -10
  252. package/src/engine/internal/tool-exposure.ts +22 -18
  253. package/src/engine/internal/tool-telemetry.ts +15 -12
  254. package/dist/Agent-0WvBWWbM.mjs.map +0 -1
  255. package/dist/AgentRuntime-CQ-qcETl.mjs.map +0 -1
  256. package/dist/Digest-DCuPlhNk.mjs.map +0 -1
  257. package/dist/DurableAgentRuntime-BAmSkWYr.mjs.map +0 -1
  258. package/dist/MessagingHost-CRUK4JBi.mjs.map +0 -1
  259. package/dist/RunContinuation-DHYNAQFi.mjs.map +0 -1
  260. package/dist/RunJournal-kfKVxJj7.mjs.map +0 -1
  261. package/dist/RunStorage-uqPxps09.mjs.map +0 -1
  262. package/dist/Scheduling-CVyfXlBR.mjs.map +0 -1
  263. package/dist/Subagent-vpffemql.mjs.map +0 -1
  264. package/dist/ThreadImport-DckUMEqJ.mjs.map +0 -1
  265. package/dist/ThreadStore-CEekRa80.mjs.map +0 -1
  266. package/dist/agent-registration-ByMZ_cK5.mjs.map +0 -1
@@ -33,11 +33,13 @@ const EncodedMemoryChange = Schema.Struct({
33
33
  resultJson: StoredJson,
34
34
  });
35
35
 
36
- const equivalentContent = Schema.toEquivalence(
37
- Schema.toEncoded(MemoryWrite.Wire.members[0].fields.content),
38
- );
36
+ const makeEquivalentContent = () =>
37
+ Schema.toEquivalence(Schema.toEncoded(MemoryWrite.Wire.members[0].fields.content));
38
+
39
+ let equivalentContent: ReturnType<typeof makeEquivalentContent> | undefined;
39
40
 
40
- const equivalentScopes = Schema.toEquivalence(MemoryWrite.Wire.members[0].fields.scopes);
41
+ const makeEquivalentScopes = () => Schema.toEquivalence(MemoryWrite.Wire.members[0].fields.scopes);
42
+ let equivalentScopes: ReturnType<typeof makeEquivalentScopes> | undefined;
41
43
 
42
44
  /** Ordered commands committed atomically by the SQL memory adapter. */
43
45
  export const SqlMemoryWriteBatch = Schema.Array(MemoryWrite.Wire).check(Schema.isMaxLength(128));
@@ -388,8 +390,8 @@ const validateReceiptResult = Effect.fnUntraced(function* (
388
390
  return yield* storageError(operation, "corrupt");
389
391
  }
390
392
  if (
391
- !equivalentContent(command.content, result.content) ||
392
- !equivalentScopes(command.scopes, result.scopes)
393
+ !(equivalentContent ??= makeEquivalentContent())(command.content, result.content) ||
394
+ !(equivalentScopes ??= makeEquivalentScopes())(command.scopes, result.scopes)
393
395
  ) {
394
396
  return yield* storageError(operation, "corrupt");
395
397
  }
@@ -228,6 +228,10 @@ export class SubmissionSnapshot extends Schema.Class<SubmissionSnapshot>(
228
228
  inputPayload: PersistedJson,
229
229
  inputDigest: Digest,
230
230
  settledOutcome: Schema.optionalKey(SettlementOutcome),
231
+ /** First committed finalization time; paired with settledRecordId by native adapters. */
232
+ settledAt: Schema.optionalKey(Schema.DateTimeUtcFromString),
233
+ /** Exact canonical settlement behind the finalized projection; not a substitute for reading it. */
234
+ settledRecordId: Schema.optionalKey(RecordId),
231
235
  createdAt: Schema.DateTimeUtcFromString,
232
236
  readyAt: Schema.optionalKey(Schema.DateTimeUtcFromString),
233
237
  admissionGroup: Schema.optionalKey(AdmissionGroup),
@@ -985,6 +989,10 @@ export type SubmissionLedgerFailure =
985
989
  * An optional `parentLinkage` is recorded immutably at first admission (SUB-016); a replay
986
990
  * whose linkage diverges (present vs. absent, or different identities) fails with
987
991
  * `AdmissionConflict` even when the input digest matches.
992
+ * With `readyIfInitialized`, an adapter may insert a fresh ordinary Submission as ready
993
+ * when it proves Thread initialization under the admission's owner transaction. Readiness,
994
+ * its lifecycle fact and source progress commit with the receipt. Otherwise it returns
995
+ * admitted and the caller completes materialization and `markReady` as usual.
988
996
  * - `resolveAdmission` — authoritative tri-state admission lookup by scoped idempotency key
989
997
  * (SUB-031): `NotAdmitted` proves absence, `Admitted` carries the full snapshot, and
990
998
  * `Indeterminate` states that the adapter cannot currently prove either. Only `NotAdmitted`
@@ -1089,6 +1097,7 @@ export class SubmissionLedger extends Context.Service<
1089
1097
  readonly capabilities: Effect.Effect<LedgerCapabilities>;
1090
1098
  readonly admit: (
1091
1099
  request: AdmissionRequest,
1100
+ options?: { readonly readyIfInitialized?: boolean },
1092
1101
  ) => Effect.Effect<AdmissionResult, AdmissionConflict | AdmissionPolicyError | LedgerError>;
1093
1102
  readonly markReady: (request: MarkReadyRequest) => Effect.Effect<void, LedgerError>;
1094
1103
  readonly lookup: (
@@ -1164,6 +1173,8 @@ export class SubmissionLedger extends Context.Service<
1164
1173
  request: ReleaseChildBudgetRequest,
1165
1174
  ) => Effect.Effect<ChildBudgetReservationSnapshot, ChildReservationConflict | LedgerError>;
1166
1175
  readonly scanNonterminal: Stream.Stream<SubmissionWorkItem, LedgerError>;
1176
+ /** Optional native snapshot for hosts that need the complete control worklist. */
1177
+ readonly listNonterminal?: Effect.Effect<ReadonlyArray<SubmissionWorkItem>, LedgerError>;
1167
1178
  readonly loadRecoverySnapshot: (
1168
1179
  request: RecoverySnapshotRequest,
1169
1180
  ) => Effect.Effect<RecoverySnapshot, LedgerError>;
@@ -122,8 +122,8 @@ export const makeSubscriptionInputBinding = Effect.fnUntraced(function* <
122
122
  Effect.scoped,
123
123
  Effect.provideContext(services),
124
124
  ),
125
- prepare: (event, subscription) =>
126
- Effect.gen(function* () {
125
+ prepare: Effect.fnUntraced(
126
+ function* (event, subscription) {
127
127
  const e = yield* Schema.decodeEffect(options.event)(event.payload).pipe(
128
128
  Effect.mapError(invalid),
129
129
  );
@@ -137,6 +137,8 @@ export const makeSubscriptionInputBinding = Effect.fnUntraced(function* <
137
137
  ).pipe(Effect.mapError(invalid));
138
138
 
139
139
  return yield* encode(options.input, yield* options.prepare(e, p, c));
140
- }).pipe(Effect.scoped, Effect.provideContext(services)),
140
+ },
141
+ (effect) => effect.pipe(Effect.scoped, Effect.provideContext(services)),
142
+ ),
141
143
  };
142
144
  });
@@ -860,21 +860,20 @@ const lifetimeCapacity = conformanceCase(
860
860
  );
861
861
  }
862
862
 
863
- const assertHostGuard = <A>(
863
+ const assertHostGuard = Effect.fnUntraced(function* <A>(
864
864
  effect: Effect.Effect<A, SubscriptionStoreFailure>,
865
865
  code: string,
866
- ) =>
867
- Effect.gen(function* () {
868
- const result = yield* Effect.result(effect);
869
-
870
- yield* ensure(
871
- Result.isFailure(result) &&
872
- result.failure._tag === "SubscriptionError" &&
873
- result.failure.reason === "capacity" &&
874
- result.failure.code === code,
875
- `host ${code} guard ignored live work`,
876
- );
877
- });
866
+ ) {
867
+ const result = yield* Effect.result(effect);
868
+
869
+ yield* ensure(
870
+ Result.isFailure(result) &&
871
+ result.failure._tag === "SubscriptionError" &&
872
+ result.failure.reason === "capacity" &&
873
+ result.failure.code === code,
874
+ `host ${code} guard ignored live work`,
875
+ );
876
+ });
878
877
 
879
878
  const active = yield* store.register(record("host-active"), limits);
880
879
  const activeEvent = yield* store.accept(event("host-active"), limits);
@@ -934,17 +933,18 @@ const capacityReactivation = conformanceCase(
934
933
  maxDeliveriesPerOwner: 1,
935
934
  };
936
935
 
937
- const expectCapacity = <A>(effect: Effect.Effect<A, SubscriptionStoreFailure>) =>
938
- Effect.gen(function* () {
939
- const result = yield* Effect.result(effect);
936
+ const expectCapacity = Effect.fnUntraced(function* <A>(
937
+ effect: Effect.Effect<A, SubscriptionStoreFailure>,
938
+ ) {
939
+ const result = yield* Effect.result(effect);
940
940
 
941
- yield* ensure(
942
- Result.isFailure(result) &&
943
- result.failure._tag === "SubscriptionError" &&
944
- result.failure.reason === "capacity",
945
- "live work did not reserve capacity",
946
- );
947
- });
941
+ yield* ensure(
942
+ Result.isFailure(result) &&
943
+ result.failure._tag === "SubscriptionError" &&
944
+ result.failure.reason === "capacity",
945
+ "live work did not reserve capacity",
946
+ );
947
+ });
948
948
 
949
949
  const expiring = record("expiring");
950
950
 
@@ -584,25 +584,24 @@ const makeManagement = Effect.fnUntraced(function* (requested: SubscriptionLimit
584
584
 
585
585
  return Subscriptions.of({
586
586
  getSubscription,
587
- recoverSubscription: (scopeValue, key, expectedRevision) =>
588
- Effect.gen(function* () {
589
- const owner = yield* scope(scopeValue);
590
-
591
- yield* authorizer.manage("recover", owner);
592
-
593
- return snapshot(
594
- yield* store.change(
595
- yield* ownedKey(owner, key),
596
- expectedRevision,
597
- {
598
- _tag: "Recover",
599
- nowMillis: yield* now,
600
- },
601
- limits,
602
- ),
603
- yield* now,
604
- );
605
- }),
587
+ recoverSubscription: Effect.fnUntraced(function* (scopeValue, key, expectedRevision) {
588
+ const owner = yield* scope(scopeValue);
589
+
590
+ yield* authorizer.manage("recover", owner);
591
+
592
+ return snapshot(
593
+ yield* store.change(
594
+ yield* ownedKey(owner, key),
595
+ expectedRevision,
596
+ {
597
+ _tag: "Recover",
598
+ nowMillis: yield* now,
599
+ },
600
+ limits,
601
+ ),
602
+ yield* now,
603
+ );
604
+ }),
606
605
  recoverDelivery,
607
606
  subscribe,
608
607
  updateSubscription,
@@ -701,28 +701,27 @@ export const prepareImportPage = Effect.fnUntraced(function* (
701
701
  return { archive, records, batches: prepared } satisfies PreparedImportPage;
702
702
  });
703
703
 
704
- export const finishThreadImport = (state: ThreadImportProgress) =>
705
- Effect.gen(function* () {
706
- const page = state.manifest;
704
+ export const finishThreadImport = Effect.fnUntraced(function* (state: ThreadImportProgress) {
705
+ const page = state.manifest;
707
706
 
708
- if (
709
- page === undefined ||
710
- !state.ended ||
711
- state.sequence !== page.tailSequence ||
712
- transferSections.some((section) => state.counts[section] !== page.snapshot[section])
713
- )
714
- return yield* invalid(
715
- "Transfer stream ended before its complete canonical sequence and fact sections",
716
- );
707
+ if (
708
+ page === undefined ||
709
+ !state.ended ||
710
+ state.sequence !== page.tailSequence ||
711
+ transferSections.some((section) => state.counts[section] !== page.snapshot[section])
712
+ )
713
+ return yield* invalid(
714
+ "Transfer stream ended before its complete canonical sequence and fact sections",
715
+ );
717
716
 
718
- return ThreadImportResult.make({
719
- threadId: page.threadId,
720
- format: page.format,
721
- tailSequence: page.tailSequence,
722
- recordCount: state.sequence,
723
- submissionCount: state.counts.admissions,
724
- });
717
+ return ThreadImportResult.make({
718
+ threadId: page.threadId,
719
+ format: page.format,
720
+ tailSequence: page.tailSequence,
721
+ recordCount: state.sequence,
722
+ submissionCount: state.counts.admissions,
725
723
  });
724
+ });
726
725
 
727
726
  /** An executed receipt must settle strictly after its own input. FIFO inputs are checked in one pass. */
728
727
  export const verifyImportedInputOrder = Effect.fnUntraced(function* (
@@ -130,7 +130,8 @@ export const verifyThreadInvariants = Effect.fnUntraced(function* <E, R>(
130
130
  selected === undefined ||
131
131
  selected.sequence !== entry.sequence ||
132
132
  selected.batchId !== entry.batchId ||
133
- recordEncoding(selected.record).json !== recordEncoding(entry.record).json
133
+ (yield* Effect.fromResult(recordEncoding(selected.record))).json !==
134
+ (yield* Effect.fromResult(recordEncoding(entry.record))).json
134
135
  )
135
136
  fail(
136
137
  "continuation-evidence",
@@ -1,4 +1,4 @@
1
- import { Context, Effect, Layer, Option, Predicate, Result, Schema, Stream, Struct } from "effect";
1
+ import { Context, Effect, Layer, Option, Result, Schema, Stream, Struct } from "effect";
2
2
 
3
3
  import { ReceiptId, RunId, SubmissionId, ThreadId, ToolCallId } from "../core/Identifiers.ts";
4
4
  import { utf8ByteLength } from "../core/internal/utf8.ts";
@@ -189,10 +189,10 @@ const selectedRecords = Effect.fnUntraced(function* (
189
189
  )
190
190
  return yield* incomplete("read selection identity");
191
191
  afterSequence = entry.sequence;
192
- bytes += yield* Effect.try({
193
- try: () => recordEncoding(entry.record).bytes,
194
- catch: () => incomplete("read selection bytes"),
195
- });
192
+ bytes += yield* Effect.fromResult(recordEncoding(entry.record)).pipe(
193
+ Effect.map((record) => record.bytes),
194
+ Effect.mapError(() => incomplete("read selection bytes")),
195
+ );
196
196
  if (bytes > MAX_THREAD_EXPORT_PAGE_BYTES)
197
197
  return yield* incomplete("read selection byte limit");
198
198
  records.push(entry);
@@ -356,11 +356,103 @@ const validateRecordCount = Schema.decodeUnknownSync(
356
356
  Schema.Array(Schema.Unknown).check(Schema.isMaxLength(256)),
357
357
  );
358
358
 
359
- const executionJson = Schema.fromJsonString(ExecutionUpdate);
360
- const encodeExecution = Schema.encodeSync(executionJson);
361
- const decodeExecution = Schema.decodeUnknownSync(ExecutionUpdate);
359
+ const validateExecutionHeader = Schema.decodeUnknownSync(
360
+ Schema.Struct({
361
+ previousRevision: ExecutionUpdate.fields.previousRevision,
362
+ retire: ExecutionUpdate.fields.retire,
363
+ checkpoint: Schema.Struct({
364
+ version: ExecutionCheckpoint.fields.version,
365
+ canonicalRecords: ExecutionCheckpoint.fields.canonicalRecords,
366
+ originalSequence: ExecutionCheckpoint.fields.originalSequence,
367
+ throughSequence: ExecutionCheckpoint.fields.throughSequence,
368
+ batchId: ExecutionCheckpoint.fields.batchId,
369
+ }),
370
+ }),
371
+ );
372
+
373
+ const validateExecutionRecordCount = Schema.decodeUnknownSync(
374
+ Schema.Array(Schema.Unknown).check(Schema.isMaxLength(8)),
375
+ );
376
+
377
+ /** Capture records once; wrapper fields retain their owning Schema's constraints. */
378
+ const captureExecution = (input: ExecutionUpdate) => {
379
+ const header = validateExecutionHeader(input);
380
+ const operationalInput = input.checkpoint.operational;
381
+ const factsInput = input.facts;
382
+
383
+ const operationalLength = validateExecutionRecordCount(operationalInput).length;
384
+ const factsLength = validateExecutionRecordCount(factsInput).length;
362
385
 
363
- const capturedAppends = new WeakMap<AppendRequest, PreparedAppend>();
386
+ const progress = captureRecord(input.checkpoint.progressRecord);
387
+
388
+ if (Result.isFailure(progress)) return Result.fail(progress.failure);
389
+ const progressRecord = progress.success.canonical;
390
+
391
+ if (!isExecutionProgressRecord(progressRecord))
392
+ return Result.fail(
393
+ ThreadStoreError.make({
394
+ operation: "prepare durable commit",
395
+ message: "Expected a Run continuation record",
396
+ }),
397
+ );
398
+
399
+ // Use the Schema-validated indexed lengths, never a caller's iterator. Sparse slots
400
+ // still visit the record boundary, where undefined is refused.
401
+ const operational = [];
402
+
403
+ for (let index = 0; index < operationalLength; index++) {
404
+ const record = captureRecord(operationalInput[index]!);
405
+
406
+ if (Result.isFailure(record)) return Result.fail(record.failure);
407
+ operational.push(record.success);
408
+ }
409
+ const facts = [];
410
+
411
+ for (let index = 0; index < factsLength; index++) {
412
+ const record = captureRecord(factsInput[index]!);
413
+
414
+ if (Result.isFailure(record)) return Result.fail(record.failure);
415
+ facts.push(record.success);
416
+ }
417
+
418
+ const checkpoint = Object.freeze(
419
+ ExecutionCheckpoint.make(
420
+ {
421
+ ...header.checkpoint,
422
+ progressRecord,
423
+ operational: Object.freeze(operational.map(({ canonical }) => canonical)),
424
+ },
425
+ { disableChecks: true },
426
+ ),
427
+ );
428
+
429
+ const update = Object.freeze(
430
+ ExecutionUpdate.make(
431
+ {
432
+ previousRevision: header.previousRevision,
433
+ retire: header.retire,
434
+ checkpoint,
435
+ facts: Object.freeze(facts.map(({ canonical }) => canonical)),
436
+ },
437
+ { disableChecks: true },
438
+ ),
439
+ );
440
+
441
+ const checkpointJson = `{"version":${checkpoint.version},"progressRecord":${progress.success.json},"operational":[${operational.map(({ json }) => json).join(",")}],"canonicalRecords":${checkpoint.canonicalRecords},"originalSequence":${checkpoint.originalSequence},"throughSequence":${checkpoint.throughSequence},"batchId":${JSON.stringify(checkpoint.batchId)}}`;
442
+ const json = `{"previousRevision":${update.previousRevision},"checkpoint":${checkpointJson},"facts":[${facts.map(({ json }) => json).join(",")}],"retire":${update.retire}}`;
443
+
444
+ return Result.succeed(
445
+ Object.freeze({
446
+ update,
447
+ json,
448
+ checkpointJson,
449
+ factsJson: JSON.stringify(facts.map(({ wire }) => wire)),
450
+ bytes: utf8ByteLength(json),
451
+ }),
452
+ );
453
+ };
454
+
455
+ const capturedAppends = new WeakMap<AppendRequest, CapturedAppend>();
364
456
 
365
457
  /**
366
458
  * Admission reserves one complete batch's envelope, references, snapshot and continuation cursor.
@@ -407,6 +499,8 @@ export interface PreparedAppend extends AppendRequest {
407
499
  readonly json: string;
408
500
  /** Checkpoint wire from the same detached, validated execution capture. */
409
501
  readonly checkpointJson: string;
502
+ /** Schema-encoded fact array from this same capture, for the stable retry digest. */
503
+ readonly factsJson: string;
410
504
  readonly bytes: number;
411
505
  }>;
412
506
  readonly records: ReadonlyArray<{
@@ -418,122 +512,123 @@ export interface PreparedAppend extends AppendRequest {
418
512
  }>;
419
513
  }
420
514
 
515
+ interface CapturedAppend extends PreparedAppend {
516
+ readonly records: ReadonlyArray<
517
+ Omit<PreparedAppend["records"][number], "wire"> & {
518
+ readonly wire: typeof RecordEnvelope.Encoded;
519
+ }
520
+ >;
521
+ }
522
+
421
523
  export const PreparedAppend = {
422
- capture: (input: AppendRequest): Effect.Effect<PreparedAppend, ThreadStoreError> =>
524
+ capture: (input: AppendRequest): Effect.Effect<CapturedAppend, ThreadStoreError> =>
423
525
  Effect.suspend(() => {
424
526
  const existing = capturedAppends.get(input);
425
527
 
426
528
  if (existing !== undefined) return Effect.succeed(existing);
427
529
 
428
530
  return Effect.try({
429
- try: () => {
430
- const header = validateHeader({
431
- ...input,
432
- batchId: input.batch.batchId,
433
- producerId: input.batch.producerId,
434
- });
435
-
436
- validateRecordCount(input.batch.records);
437
- validateRecordCount(input.executions ?? []);
438
-
439
- const executionWrites = Object.freeze(
440
- (input.executions ?? []).map((update) => {
441
- const json = encodeExecution(update);
442
- const wire: unknown = JSON.parse(json);
443
- const decoded = decodeExecution(wire);
444
-
445
- if (!Predicate.hasProperty(wire, "checkpoint"))
446
- throw ThreadStoreError.make({
447
- operation: "prepare durable commit",
448
- message: "Captured execution has no checkpoint wire",
449
- });
450
-
451
- return Object.freeze({
452
- update: decoded,
453
- json,
454
- checkpointJson: JSON.stringify(wire.checkpoint),
455
- bytes: utf8ByteLength(json),
456
- });
457
- }),
458
- );
459
-
460
- if (input.batch.records.length === 0 && executionWrites.length === 0)
461
- throw ThreadStoreError.make({
462
- operation: "prepare durable commit",
463
- message: "A commit must contain history facts or an active execution transition",
464
- });
465
- if (executionWrites.some(({ bytes }) => !transferPageFits(header.threadId, bytes)))
466
- throw ThreadStoreError.make({
467
- operation: "prepare durable commit",
468
- message: "Active state exceeds its bounded transfer representation",
469
- });
470
- // Visit sparse slots too: capture owns each record's validation boundary.
471
- const encodings = Array.from(input.batch.records, captureRecord);
472
- const prefix = `{"batchId":${JSON.stringify(header.batchId)},"producerId":${JSON.stringify(header.producerId)},"records":[`;
473
- const batchJson = `${prefix}${encodings.map(({ json }) => json).join(",")}]}`;
474
-
475
- const batchBytes = encodings.reduce(
476
- (total, record) => total + record.bytes,
477
- utf8ByteLength(prefix) + (encodings.length === 0 ? 2 : encodings.length + 1),
478
- );
479
-
480
- if (batchBytes > MAX_CANONICAL_BATCH_BYTES)
481
- throw ThreadStoreError.make({
482
- operation: "prepare canonical append",
483
- message: `Canonical batch exceeds ${MAX_CANONICAL_BATCH_BYTES} bytes`,
531
+ try: () =>
532
+ Result.gen(function* () {
533
+ const header = validateHeader({
534
+ ...input,
535
+ batchId: input.batch.batchId,
536
+ producerId: input.batch.producerId,
484
537
  });
485
538
 
486
- const batch = Object.freeze(
487
- new CommitBatch(
539
+ validateRecordCount(input.batch.records);
540
+ const executions = input.executions ?? [];
541
+ const executionLength = validateRecordCount(executions).length;
542
+
543
+ const executionWrites: Array<PreparedAppend["executionWrites"][number]> = [];
544
+
545
+ for (let index = 0; index < executionLength; index++)
546
+ executionWrites.push(yield* captureExecution(executions[index]!));
547
+ Object.freeze(executionWrites);
548
+
549
+ if (input.batch.records.length === 0 && executionWrites.length === 0)
550
+ return yield* Result.fail(
551
+ ThreadStoreError.make({
552
+ operation: "prepare durable commit",
553
+ message: "A commit must contain history facts or an active execution transition",
554
+ }),
555
+ );
556
+ if (executionWrites.some(({ bytes }) => !transferPageFits(header.threadId, bytes)))
557
+ return yield* Result.fail(
558
+ ThreadStoreError.make({
559
+ operation: "prepare durable commit",
560
+ message: "Active state exceeds its bounded transfer representation",
561
+ }),
562
+ );
563
+ // Visit sparse slots too: capture owns each record's validation boundary.
564
+ const encodings = yield* Result.all(Array.from(input.batch.records, captureRecord));
565
+ const prefix = `{"batchId":${JSON.stringify(header.batchId)},"producerId":${JSON.stringify(header.producerId)},"records":[`;
566
+ const batchJson = `${prefix}${encodings.map(({ json }) => json).join(",")}]}`;
567
+
568
+ const batchBytes = encodings.reduce(
569
+ (total, record) => total + record.bytes,
570
+ utf8ByteLength(prefix) + (encodings.length === 0 ? 2 : encodings.length + 1),
571
+ );
572
+
573
+ if (batchBytes > MAX_CANONICAL_BATCH_BYTES)
574
+ return yield* Result.fail(
575
+ ThreadStoreError.make({
576
+ operation: "prepare canonical append",
577
+ message: `Canonical batch exceeds ${MAX_CANONICAL_BATCH_BYTES} bytes`,
578
+ }),
579
+ );
580
+
581
+ const batch = Object.freeze(
582
+ CommitBatch.make(
583
+ {
584
+ batchId: header.batchId,
585
+ producerId: header.producerId,
586
+ records: Object.freeze(encodings.map(({ canonical }) => canonical)),
587
+ },
588
+ { disableChecks: true },
589
+ ),
590
+ );
591
+
592
+ const request = AppendRequest.make(
488
593
  {
489
- batchId: header.batchId,
490
- producerId: header.producerId,
491
- records: Object.freeze(encodings.map(({ canonical }) => canonical)),
594
+ threadId: header.threadId,
595
+ expectedTailSequence: header.expectedTailSequence,
596
+ batch,
597
+ ...(executionWrites.length === 0
598
+ ? {}
599
+ : { executions: Object.freeze(executionWrites.map(({ update }) => update)) }),
492
600
  },
493
601
  { disableChecks: true },
494
- ),
495
- );
496
-
497
- const request = new AppendRequest(
498
- {
499
- threadId: header.threadId,
500
- expectedTailSequence: header.expectedTailSequence,
501
- batch,
502
- ...(executionWrites.length === 0
503
- ? {}
504
- : { executions: Object.freeze(executionWrites.map(({ update }) => update)) }),
505
- },
506
- { disableChecks: true },
507
- );
508
-
509
- const records = Object.freeze(
510
- encodings.map(({ canonical, json, wire, bytes }) =>
511
- Object.freeze({
512
- recordId: canonical.recordId,
513
- recordJson: json,
514
- recordBytes: bytes,
515
- wire,
516
- canonical,
602
+ );
603
+
604
+ const records = Object.freeze(
605
+ encodings.map(({ canonical, json, wire, bytes }) =>
606
+ Object.freeze({
607
+ recordId: canonical.recordId,
608
+ recordJson: json,
609
+ recordBytes: bytes,
610
+ wire,
611
+ canonical,
612
+ }),
613
+ ),
614
+ );
615
+
616
+ const progress = Object.freeze(encodings.map(({ progress }) => progress));
617
+
618
+ const captured = Object.freeze(
619
+ Object.assign(request, {
620
+ batchJson,
621
+ batchBytes,
622
+ records,
623
+ progress,
624
+ executionWrites,
517
625
  }),
518
- ),
519
- );
520
-
521
- const progress = Object.freeze(encodings.map(({ progress }) => progress));
626
+ );
522
627
 
523
- const captured = Object.freeze(
524
- Object.assign(request, {
525
- batchJson,
526
- batchBytes,
527
- records,
528
- progress,
529
- executionWrites,
530
- }),
531
- );
628
+ capturedAppends.set(captured, captured);
532
629
 
533
- capturedAppends.set(captured, captured);
534
-
535
- return captured;
536
- },
630
+ return captured;
631
+ }),
537
632
  catch: (cause) =>
538
633
  Schema.is(ThreadStoreError)(cause)
539
634
  ? cause
@@ -544,7 +639,18 @@ export const PreparedAppend = {
544
639
  : "Canonical append capture failed",
545
640
  cause,
546
641
  }),
547
- });
642
+ }).pipe(
643
+ Effect.flatMap(Effect.fromResult),
644
+ Effect.mapError((cause) =>
645
+ Schema.is(ThreadStoreError)(cause)
646
+ ? cause
647
+ : ThreadStoreError.make({
648
+ operation: "prepare canonical append",
649
+ message: cause.message,
650
+ cause,
651
+ }),
652
+ ),
653
+ );
548
654
  }),
549
655
  };
550
656