@effect-agent/storage-cloudflare 0.1.0-beta.79 → 0.1.0-beta.80

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.
@@ -1,7 +1,7 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
2
  import { DoStorageConfig } from "./DoStorageConfig.mjs";
3
3
  import { DoStorageFailpoint } from "./DoStorageFailpoint.mjs";
4
- import { a as initializeDoJournal } from "./do-journal-DnzUmhPA.mjs";
4
+ import { a as initializeDoJournal } from "./do-journal-DHqCQeBU.mjs";
5
5
  import { MessageDeliveryError, MessageDeliveryStore } from "@effect-agent/thread/MessageDelivery";
6
6
  import { SqlMessageDeliveryTransaction, makeSqlMessageDeliveryStore } from "@effect-agent/thread/SqlMessageDeliveryStore";
7
7
  import { Effect, Layer } from "effect";
@@ -2,7 +2,7 @@ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
2
  import { DoStorageConfig } from "./DoStorageConfig.mjs";
3
3
  import { DoStorageFailpoint } from "./DoStorageFailpoint.mjs";
4
4
  import { DoLedgerError, DoStorageCorruptionError, DoStorageError } from "./DoStorageError.mjs";
5
- import { a as initializeDoJournal, i as decodeRows } from "./do-journal-DnzUmhPA.mjs";
5
+ import { a as initializeDoJournal, i as decodeRows } from "./do-journal-DHqCQeBU.mjs";
6
6
  import { storageConfigLayer, storageFailpointLayer } from "./DoThreadStore.mjs";
7
7
  import { Clock, Context, Crypto, DateTime, Effect, Layer, Option, Schema, Stream } from "effect";
8
8
  import * as SqlClientService from "effect/unstable/sql/SqlClient";
@@ -2,7 +2,7 @@ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
2
  import { DoStorageConfig, DoStorageConfigValue } from "./DoStorageConfig.mjs";
3
3
  import { DoStorageFailpoint } from "./DoStorageFailpoint.mjs";
4
4
  import { DoAppendConflict, DoCheckpointConflict, DoFenceRejected, DoStorageCorruptionError, DoStorageError } from "./DoStorageError.mjs";
5
- import { a as initializeDoJournal, n as RawCheckpoint, r as RawReadRequest, t as RawAppendRequest } from "./do-journal-DnzUmhPA.mjs";
5
+ import { a as initializeDoJournal, n as RawCheckpoint, r as RawReadRequest, t as RawAppendRequest } from "./do-journal-DHqCQeBU.mjs";
6
6
  import { Clock, Context, Crypto, Duration, Effect, Layer, Option, Ref, Schema, Stream } from "effect";
7
7
  import * as SqlClientService from "effect/unstable/sql/SqlClient";
8
8
  import { EMPTY_TAIL_DIGEST, digestCanonicalBatch } from "@effect-agent/thread/Digest";
@@ -350,6 +350,11 @@ declare const encodePortRequest: (input: LedgerAdmitCall | LedgerLookupCall | Le
350
350
  readonly createdAt: string;
351
351
  readonly deploymentId: string;
352
352
  readonly payload: {
353
+ readonly _tag: "AbortRequested";
354
+ readonly submissionId: string;
355
+ readonly author: string;
356
+ readonly reason: string;
357
+ } | {
353
358
  readonly _tag: "ThreadCreated";
354
359
  readonly agentId: string;
355
360
  readonly definitions: {
@@ -524,11 +529,6 @@ declare const encodePortRequest: (input: LedgerAdmitCall | LedgerLookupCall | Le
524
529
  readonly runDisposition?: Schema.Json | undefined;
525
530
  readonly finishReason?: "budget-exhausted" | undefined;
526
531
  readonly exhausted?: "tokens" | "tool-calls" | "turns" | undefined;
527
- } | {
528
- readonly _tag: "AbortRequested";
529
- readonly submissionId: string;
530
- readonly author: string;
531
- readonly reason: string;
532
532
  } | {
533
533
  readonly _tag: "SubmissionSettled";
534
534
  readonly submissionId: string;
@@ -963,6 +963,11 @@ declare const encodePortRequest: (input: LedgerAdmitCall | LedgerLookupCall | Le
963
963
  readonly createdAt: string;
964
964
  readonly deploymentId: string;
965
965
  readonly payload: {
966
+ readonly _tag: "AbortRequested";
967
+ readonly submissionId: string;
968
+ readonly author: string;
969
+ readonly reason: string;
970
+ } | {
966
971
  readonly _tag: "ThreadCreated";
967
972
  readonly agentId: string;
968
973
  readonly definitions: {
@@ -1137,11 +1142,6 @@ declare const encodePortRequest: (input: LedgerAdmitCall | LedgerLookupCall | Le
1137
1142
  readonly runDisposition?: Schema.Json | undefined;
1138
1143
  readonly finishReason?: "budget-exhausted" | undefined;
1139
1144
  readonly exhausted?: "tokens" | "tool-calls" | "turns" | undefined;
1140
- } | {
1141
- readonly _tag: "AbortRequested";
1142
- readonly submissionId: string;
1143
- readonly author: string;
1144
- readonly reason: string;
1145
1145
  } | {
1146
1146
  readonly _tag: "SubmissionSettled";
1147
1147
  readonly submissionId: string;
@@ -1905,6 +1905,11 @@ declare const encodePortResponse: (input: PortFailed | PortSucceeded, options?:
1905
1905
  readonly createdAt: string;
1906
1906
  readonly deploymentId: string;
1907
1907
  readonly payload: {
1908
+ readonly _tag: "AbortRequested";
1909
+ readonly submissionId: string;
1910
+ readonly author: string;
1911
+ readonly reason: string;
1912
+ } | {
1908
1913
  readonly _tag: "ThreadCreated";
1909
1914
  readonly agentId: string;
1910
1915
  readonly definitions: {
@@ -2079,11 +2084,6 @@ declare const encodePortResponse: (input: PortFailed | PortSucceeded, options?:
2079
2084
  readonly runDisposition?: Schema.Json | undefined;
2080
2085
  readonly finishReason?: "budget-exhausted" | undefined;
2081
2086
  readonly exhausted?: "tokens" | "tool-calls" | "turns" | undefined;
2082
- } | {
2083
- readonly _tag: "AbortRequested";
2084
- readonly submissionId: string;
2085
- readonly author: string;
2086
- readonly reason: string;
2087
2087
  } | {
2088
2088
  readonly _tag: "SubmissionSettled";
2089
2089
  readonly submissionId: string;
@@ -2540,6 +2540,11 @@ declare const encodePortResponse: (input: PortFailed | PortSucceeded, options?:
2540
2540
  readonly createdAt: string;
2541
2541
  readonly deploymentId: string;
2542
2542
  readonly payload: {
2543
+ readonly _tag: "AbortRequested";
2544
+ readonly submissionId: string;
2545
+ readonly author: string;
2546
+ readonly reason: string;
2547
+ } | {
2543
2548
  readonly _tag: "ThreadCreated";
2544
2549
  readonly agentId: string;
2545
2550
  readonly definitions: {
@@ -2714,11 +2719,6 @@ declare const encodePortResponse: (input: PortFailed | PortSucceeded, options?:
2714
2719
  readonly runDisposition?: Schema.Json | undefined;
2715
2720
  readonly finishReason?: "budget-exhausted" | undefined;
2716
2721
  readonly exhausted?: "tokens" | "tool-calls" | "turns" | undefined;
2717
- } | {
2718
- readonly _tag: "AbortRequested";
2719
- readonly submissionId: string;
2720
- readonly author: string;
2721
- readonly reason: string;
2722
2722
  } | {
2723
2723
  readonly _tag: "SubmissionSettled";
2724
2724
  readonly submissionId: string;
@@ -3153,25 +3153,8 @@ declare const encodePortResponse: (input: PortFailed | PortSucceeded, options?:
3153
3153
  } | {
3154
3154
  readonly _tag: "PortFailed";
3155
3155
  readonly failure: {
3156
- readonly _tag: "FenceRejected";
3157
- readonly threadId: string;
3158
- readonly actualEpoch: number;
3159
- readonly attemptedEpoch: number;
3160
- } | {
3161
- readonly _tag: "ThreadStoreError";
3162
- readonly operation: string;
3156
+ readonly _tag: "PortProtocolError";
3163
3157
  readonly message: string;
3164
- readonly cause?: Schema.Json | undefined;
3165
- } | {
3166
- readonly _tag: "ThreadNotMaterialized";
3167
- readonly threadId: string;
3168
- } | {
3169
- readonly _tag: "AppendConflict";
3170
- readonly threadId: string;
3171
- readonly batchId: string;
3172
- readonly reason: "batch-digest" | "record-identity" | "tail";
3173
- readonly actualTailSequence?: number | undefined;
3174
- readonly actualTailDigest?: string | undefined;
3175
3158
  } | {
3176
3159
  readonly _tag: "AdmissionConflict";
3177
3160
  readonly threadId: string;
@@ -3188,17 +3171,34 @@ declare const encodePortResponse: (input: PortFailed | PortSucceeded, options?:
3188
3171
  readonly operation: string;
3189
3172
  readonly message: string;
3190
3173
  readonly cause?: Schema.Json | undefined;
3191
- } | {
3192
- readonly _tag: "PortProtocolError";
3193
- readonly message: string;
3194
3174
  } | {
3195
3175
  readonly _tag: "SettlementConflict";
3196
3176
  readonly submissionId: string;
3197
3177
  readonly existingOutcome: "aborted" | "completed" | "failed";
3178
+ } | {
3179
+ readonly _tag: "ThreadNotMaterialized";
3180
+ readonly threadId: string;
3181
+ } | {
3182
+ readonly _tag: "FenceRejected";
3183
+ readonly threadId: string;
3184
+ readonly actualEpoch: number;
3185
+ readonly attemptedEpoch: number;
3198
3186
  } | {
3199
3187
  readonly _tag: "JoinedToHost";
3200
3188
  readonly submissionId: string;
3201
3189
  readonly hostSubmissionId: string;
3190
+ } | {
3191
+ readonly _tag: "ThreadStoreError";
3192
+ readonly operation: string;
3193
+ readonly message: string;
3194
+ readonly cause?: Schema.Json | undefined;
3195
+ } | {
3196
+ readonly _tag: "AppendConflict";
3197
+ readonly threadId: string;
3198
+ readonly batchId: string;
3199
+ readonly reason: "batch-digest" | "record-identity" | "tail";
3200
+ readonly actualTailSequence?: number | undefined;
3201
+ readonly actualTailDigest?: string | undefined;
3202
3202
  };
3203
3203
  }, Schema.SchemaError, never>;
3204
3204
  declare const decodePortResponse: (input: unknown, options?: import("effect/SchemaAST").ParseOptions) => import("effect/Effect").Effect<PortFailed | PortSucceeded, Schema.SchemaError, never>;
@@ -40,11 +40,11 @@ declare class ThreadPortTransport extends ThreadPortTransport_base {}
40
40
  /** Construction options shared by both routed port Layers. */
41
41
  interface RoutedPortOptions {
42
42
  /**
43
- * The Thread this Durable Object owns (the Object identity rule is
44
- * `namespace.idFromName(threadId)`). Requests addressed here execute on the local
45
- * facet; requests addressed anywhere else route through the transport or fail fast typed.
43
+ * Decide whether this physical owner stores the addressed logical Thread. Local
44
+ * requests use the same SQLite facets; foreign requests use the transport or fail
45
+ * fast typed. The predicate determines placement, never caller authorization.
46
46
  */
47
- readonly localThreadId: ThreadId;
47
+ readonly ownsThread: (threadId: ThreadId) => boolean;
48
48
  }
49
49
  /**
50
50
  * Routing decorator over the LOCAL `SubmissionLedger` facet (plan §1.3): a request addressing
@@ -85,7 +85,7 @@ const LOCAL = { _tag: "local" };
85
85
  * Identities beyond the ledger's 1,024-character row bound fail typed: the minting side
86
86
  * refused them at admission, so they cannot name any stored row anywhere.
87
87
  */
88
- const routableSubmissionTarget = (localThreadId) => Effect.fn("DoPortRouting.routableSubmissionTarget")(function* (operation, submissionId) {
88
+ const routableSubmissionTarget = (ownsThread) => Effect.fn("DoPortRouting.routableSubmissionTarget")(function* (operation, submissionId) {
89
89
  if (submissionId.length > MAX_ROUTABLE_SUBMISSION_ID_LENGTH) return yield* LedgerError.make({
90
90
  operation,
91
91
  message: `A Submission identity of ${submissionId.length} characters exceeds the ${MAX_ROUTABLE_SUBMISSION_ID_LENGTH}-character routable identity bound; admission refuses such identities, so it cannot name any stored row.`
@@ -94,11 +94,10 @@ const routableSubmissionTarget = (localThreadId) => Effect.fn("DoPortRouting.rou
94
94
  if (separator === -1) return LOCAL;
95
95
  if (!UUID_HEAD_PATTERN.test(submissionId.slice(0, separator))) return LOCAL;
96
96
  const tail = submissionId.slice(separator + 1);
97
- if (tail === localThreadId) return LOCAL;
98
- return yield* decodeThreadId(tail).pipe(Effect.map((threadId) => ({
97
+ return yield* decodeThreadId(tail).pipe(Effect.map((threadId) => ownsThread(threadId) ? LOCAL : {
99
98
  _tag: "foreign",
100
99
  threadId
101
- })), Effect.orElseSucceed(() => LOCAL));
100
+ }), Effect.orElseSucceed(() => LOCAL));
102
101
  });
103
102
  const NoAdditionalPortFailure = Schema.Never;
104
103
  const AbortPortFailure = Schema.Union([SettlementConflict, JoinedToHost]);
@@ -128,7 +127,7 @@ const makeRoutedLedgerServices = Effect.fn("DoPortRouting.makeRoutedLedgerServic
128
127
  const local = yield* SubmissionLedger;
129
128
  const transport = yield* ThreadPortTransport;
130
129
  const transportCall = makeTransportCall(transport);
131
- const submissionTarget = routableSubmissionTarget(options.localThreadId);
130
+ const submissionTarget = routableSubmissionTarget(options.ownsThread);
132
131
  const routeFailure = (operation, target) => (error) => LedgerError.make({
133
132
  operation,
134
133
  message: boundPortDiagnostic(`Routed ${operation} to the Thread Object owning ${target} failed: ${error.message}`),
@@ -225,14 +224,14 @@ const makeRoutedLedgerServices = Effect.fn("DoPortRouting.makeRoutedLedgerServic
225
224
  });
226
225
  const routed = SubmissionLedger.of({
227
226
  capabilities: local.capabilities,
228
- admit: (request) => request.threadId === options.localThreadId ? local.admit(request) : foreignLedgerCall("ledger admit", request.threadId, LedgerAdmitCall.make({ request }), LedgerAdmitResult, Schema.Union([AdmissionConflict, AdmissionPolicyError])).pipe(Effect.map((reply) => reply.result)),
227
+ admit: (request) => options.ownsThread(request.threadId) ? local.admit(request) : foreignLedgerCall("ledger admit", request.threadId, LedgerAdmitCall.make({ request }), LedgerAdmitResult, Schema.Union([AdmissionConflict, AdmissionPolicyError])).pipe(Effect.map((reply) => reply.result)),
229
228
  markReady: (request) => submissionTarget("ledger mark ready", request.submissionId).pipe(Effect.flatMap((target) => target._tag === "local" ? local.markReady(request) : foreignLedgerCall("ledger mark ready", target.threadId, LedgerMarkReadyCall.make({ request }), LedgerMarkReadyResult, NoAdditionalPortFailure).pipe(Effect.asVoid))),
230
- lookup: (request) => request._tag === "SubmissionLookupById" ? submissionTarget("ledger lookup", request.submissionId).pipe(Effect.flatMap((target) => target._tag === "local" ? local.lookup(request) : foreignLookupById("ledger lookup", target.threadId, request.submissionId))) : request.threadId === options.localThreadId ? local.lookup(request) : foreignLedgerCall("ledger lookup", request.threadId, LedgerLookupCall.make({ request }), LedgerLookupResult, NoAdditionalPortFailure).pipe(Effect.map((result) => result.submission === void 0 ? Option.none() : Option.some(result.submission))),
231
- resolveAdmission: (request) => request.threadId === options.localThreadId ? local.resolveAdmission(request) : resolveForeignAdmission(request.threadId, request),
229
+ lookup: (request) => request._tag === "SubmissionLookupById" ? submissionTarget("ledger lookup", request.submissionId).pipe(Effect.flatMap((target) => target._tag === "local" ? local.lookup(request) : foreignLookupById("ledger lookup", target.threadId, request.submissionId))) : options.ownsThread(request.threadId) ? local.lookup(request) : foreignLedgerCall("ledger lookup", request.threadId, LedgerLookupCall.make({ request }), LedgerLookupResult, NoAdditionalPortFailure).pipe(Effect.map((result) => result.submission === void 0 ? Option.none() : Option.some(result.submission))),
230
+ resolveAdmission: (request) => options.ownsThread(request.threadId) ? local.resolveAdmission(request) : resolveForeignAdmission(request.threadId, request),
232
231
  requestAbort: (request) => submissionTarget("ledger request abort", request.submissionId).pipe(Effect.flatMap((target) => target._tag === "local" ? local.requestAbort(request) : foreignLedgerCall("ledger request abort", target.threadId, LedgerRequestAbortCall.make({ request }), LedgerRequestAbortResult, AbortPortFailure).pipe(Effect.map((reply) => reply.intent)))),
233
232
  recordChildSettled: (request) => submissionTarget("ledger record child settled", request.parentSubmissionId).pipe(Effect.flatMap((target) => target._tag === "local" ? local.recordChildSettled(request) : foreignLedgerCall("ledger record child settled", target.threadId, LedgerRecordChildSettledCall.make({ request }), LedgerRecordChildSettledResult, NoAdditionalPortFailure).pipe(Effect.map((reply) => reply.outcome)))),
234
- claim: (request) => request.threadId === options.localThreadId ? local.claim(request) : Effect.fail(crossThreadLedgerError("ledger claim", request.threadId)),
235
- claimJoining: (request) => request.threadId === options.localThreadId ? local.claimJoining(request) : Effect.fail(crossThreadLedgerError("ledger claim joining", request.threadId)),
233
+ claim: (request) => options.ownsThread(request.threadId) ? local.claim(request) : Effect.fail(crossThreadLedgerError("ledger claim", request.threadId)),
234
+ claimJoining: (request) => options.ownsThread(request.threadId) ? local.claimJoining(request) : Effect.fail(crossThreadLedgerError("ledger claim joining", request.threadId)),
236
235
  renewOwnership: (request) => submissionTarget("ledger renew ownership", request.submissionId).pipe(Effect.flatMap((target) => target._tag === "local" ? local.renewOwnership(request) : Effect.fail(crossThreadLedgerError("ledger renew ownership", target.threadId)))),
237
236
  releaseOwnership: (request) => submissionTarget("ledger release ownership", request.submissionId).pipe(Effect.flatMap((target) => target._tag === "local" ? local.releaseOwnership(request) : Effect.fail(crossThreadLedgerError("ledger release ownership", target.threadId)))),
238
237
  markInputApplied: (request) => submissionTarget("ledger mark input applied", request.submissionId).pipe(Effect.flatMap((target) => target._tag === "local" ? local.markInputApplied(request) : Effect.fail(crossThreadLedgerError("ledger mark input applied", target.threadId)))),
@@ -292,19 +291,19 @@ const makeRoutedStoreServices = Effect.fn("DoPortRouting.makeRoutedStoreServices
292
291
  } }));
293
292
  };
294
293
  const routed = ThreadStore.of({
295
- materialize: (request) => request.threadId === options.localThreadId ? local.materialize(request) : foreignStoreCall("thread materialize", request.threadId, StoreMaterializeCall.make({ request }), StoreMaterializeResult, FenceRejected).pipe(Effect.asVoid),
296
- append: (request) => request.threadId === options.localThreadId ? local.append(request) : foreignStoreCall("thread append", request.threadId, StoreAppendCall.make({ request }), StoreAppendResult, AppendPortFailure).pipe(Effect.map((reply) => reply.result)),
297
- read: (request) => request.threadId === options.localThreadId ? local.read(request) : Stream.unwrap(foreignStoreCall("thread read", request.threadId, StoreReadPageCall.make({ request }), StoreReadPageResult, ThreadNotMaterialized).pipe(Effect.map((reply) => Stream.fromIterable(reply.records)))),
298
- inspectTail: (request) => request.threadId === options.localThreadId ? local.inspectTail(request) : foreignStoreCall("thread inspect tail", request.threadId, StoreInspectTailCall.make({ request }), StoreInspectTailResult, ThreadNotMaterialized).pipe(Effect.map((reply) => reply.tail)),
299
- export: (request) => request.threadId === options.localThreadId ? local.export(request) : foreignStoreCall("thread export", request.threadId, StoreExportCall.make({ request }), StoreExportResult, ThreadNotMaterialized).pipe(Effect.map((reply) => reply.export)),
300
- observe: (request) => request.threadId === options.localThreadId ? local.observe(request) : Stream.unwrap(Effect.fail(crossThreadStoreError("thread observe", request.threadId))),
294
+ materialize: (request) => options.ownsThread(request.threadId) ? local.materialize(request) : foreignStoreCall("thread materialize", request.threadId, StoreMaterializeCall.make({ request }), StoreMaterializeResult, FenceRejected).pipe(Effect.asVoid),
295
+ append: (request) => options.ownsThread(request.threadId) ? local.append(request) : foreignStoreCall("thread append", request.threadId, StoreAppendCall.make({ request }), StoreAppendResult, AppendPortFailure).pipe(Effect.map((reply) => reply.result)),
296
+ read: (request) => options.ownsThread(request.threadId) ? local.read(request) : Stream.unwrap(foreignStoreCall("thread read", request.threadId, StoreReadPageCall.make({ request }), StoreReadPageResult, ThreadNotMaterialized).pipe(Effect.map((reply) => Stream.fromIterable(reply.records)))),
297
+ inspectTail: (request) => options.ownsThread(request.threadId) ? local.inspectTail(request) : foreignStoreCall("thread inspect tail", request.threadId, StoreInspectTailCall.make({ request }), StoreInspectTailResult, ThreadNotMaterialized).pipe(Effect.map((reply) => reply.tail)),
298
+ export: (request) => options.ownsThread(request.threadId) ? local.export(request) : foreignStoreCall("thread export", request.threadId, StoreExportCall.make({ request }), StoreExportResult, ThreadNotMaterialized).pipe(Effect.map((reply) => reply.export)),
299
+ observe: (request) => options.ownsThread(request.threadId) ? local.observe(request) : Stream.unwrap(Effect.fail(crossThreadStoreError("thread observe", request.threadId))),
301
300
  ...recoveryCheckpoints === void 0 ? {} : { recoveryCheckpoints: {
302
- save: (request) => request.checkpoint.threadId === options.localThreadId ? recoveryCheckpoints.save(request) : Effect.fail(crossThreadStoreError("thread save recovery checkpoint", request.checkpoint.threadId)),
303
- load: (request) => request.threadId === options.localThreadId ? recoveryCheckpoints.load(request) : Effect.succeed(Option.none())
301
+ save: (request) => options.ownsThread(request.checkpoint.threadId) ? recoveryCheckpoints.save(request) : Effect.fail(crossThreadStoreError("thread save recovery checkpoint", request.checkpoint.threadId)),
302
+ load: (request) => options.ownsThread(request.threadId) ? recoveryCheckpoints.load(request) : Effect.succeed(Option.none())
304
303
  } },
305
304
  ...checkpoints === void 0 ? {} : { checkpoints: {
306
- save: (request) => request.checkpoint.threadId === options.localThreadId ? checkpoints.save(request) : Effect.fail(crossThreadStoreError("thread save checkpoint", request.checkpoint.threadId)),
307
- load: (request) => request.threadId === options.localThreadId ? checkpoints.load(request) : Effect.fail(crossThreadStoreError("thread load checkpoint", request.threadId))
305
+ save: (request) => options.ownsThread(request.checkpoint.threadId) ? checkpoints.save(request) : Effect.fail(crossThreadStoreError("thread save checkpoint", request.checkpoint.threadId)),
306
+ load: (request) => options.ownsThread(request.threadId) ? checkpoints.load(request) : Effect.fail(crossThreadStoreError("thread load checkpoint", request.threadId))
308
307
  } }
309
308
  });
310
309
  return Context.make(ThreadStore, routed);
@@ -1 +1 @@
1
- {"version":3,"file":"PortRouting.mjs","names":[],"sources":["../src/PortRouting.ts"],"sourcesContent":["import {\n AdmissionIndeterminate,\n AdmissionConflict,\n AdmissionPolicyError,\n ChildAttachmentSnapshot,\n JoinedToHost,\n LedgerError,\n RecoverySnapshot,\n SettlementConflict,\n SubmissionLedger,\n SubmissionLookupById,\n type SubmissionLookupByKey,\n type SubmissionSnapshot,\n} from \"@effect-agent/thread/SubmissionLedger\";\nimport {\n AppendConflict,\n ThreadMaterialization,\n ThreadNotMaterialized,\n ThreadStore,\n ThreadStoreError,\n FenceRejected,\n} from \"@effect-agent/thread/ThreadStore\";\nimport { Context, Effect, Layer, Option, Predicate, Schema, Stream } from \"effect\";\n\nimport {\n boundPortDiagnostic,\n decodePortRequest,\n decodePortResponse,\n encodePortRequest,\n encodePortResponse,\n LedgerAdmitCall,\n LedgerAdmitResult,\n LedgerLookupCall,\n LedgerLookupResult,\n LedgerMarkReadyCall,\n LedgerMarkReadyResult,\n LedgerRecordChildSettledCall,\n LedgerRecordChildSettledResult,\n LedgerRequestAbortCall,\n LedgerRequestAbortResult,\n LedgerResolveAdmissionCall,\n LedgerResolveAdmissionResult,\n PortFailed,\n PortProtocolError,\n PortSucceeded,\n StoreAppendCall,\n StoreAppendResult,\n StoreExportCall,\n StoreExportResult,\n StoreInspectTailCall,\n StoreInspectTailResult,\n StoreMaterializeCall,\n StoreMaterializeResult,\n StoreReadPageCall,\n StoreReadPageResult,\n type PortFailure,\n type PortRequest,\n type PortRequestEnvelope,\n type PortResponse,\n type PortResult,\n} from \"./PortProtocol.ts\";\n\ntype ThreadId = ThreadMaterialization[\"threadId\"];\ntype SubmissionId = SubmissionSnapshot[\"submissionId\"];\n\nconst ThreadIdSchema = ThreadMaterialization.fields.threadId;\nconst decodeThreadId = Schema.decodeUnknownEffect(ThreadIdSchema);\n\n/**\n * The ledger row bound routable Submission identities must respect (mirrors the local\n * facet's `MAX_IDENTIFIER_LENGTH`; the minting side already refuses longer identities typed\n * at admission, so a longer identity presented here cannot name any stored row).\n */\nconst MAX_ROUTABLE_SUBMISSION_ID_LENGTH = 1_024;\n\n/** The `{uuidv7}` head of a DC-minted routable Submission identity. */\nconst UUID_HEAD_PATTERN =\n /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;\n\n/**\n * A transport could not deliver a port request to (or an answer from) the owning\n * Thread's Durable Object. `retryable` carries the platform's own stub signal when one\n * exists. This error never crosses the wire — it is the CALLER-side evidence that the\n * authority was unreachable, which is exactly the case `AdmissionIndeterminate` was\n * specified for (SUB-031).\n */\nexport class PortTransportError extends Schema.TaggedError<PortTransportError>()(\n \"PortTransportError\",\n {\n target: Schema.String,\n message: Schema.String,\n retryable: Schema.optionalKey(Schema.Boolean),\n cause: Schema.optionalKey(Schema.Defect()),\n },\n) {}\n\nconst safeTransportDiagnostic = (cause: unknown): string => {\n try {\n const message = cause instanceof Error ? cause.message : cause;\n\n return boundPortDiagnostic(typeof message === \"string\" ? message : String(message));\n } catch {\n return \"[unavailable transport diagnostic]\";\n }\n};\n\nconst transportRetryableSignal = (cause: unknown): boolean | undefined => {\n if (!Predicate.isObjectKeyword(cause)) return undefined;\n try {\n const signal = Reflect.get(cause, \"retryable\");\n\n return typeof signal === \"boolean\" ? signal : undefined;\n } catch {\n return undefined;\n }\n};\n\n/**\n * Build a `PortTransportError` from an arbitrary thrown transport cause, preserving the\n * platform stub's own `retryable` signal when present.\n */\nexport const portTransportFailure = (target: string, cause: unknown): PortTransportError => {\n const retryable = transportRetryableSignal(cause);\n\n return PortTransportError.make({\n target,\n message: safeTransportDiagnostic(cause),\n ...(retryable === undefined ? {} : { retryable }),\n cause,\n });\n};\n\n/**\n * Delivery of Schema-encoded port envelopes to the Durable Object that owns a FOREIGN\n * Thread (plan §1.3, D-P6-3). The shipped implementation (platform-cloudflare, WP3)\n * calls the owner's `portCall` over native Durable Object JS RPC via\n * `namespace.idFromName(threadId)`; the protocol is transport-agnostic and any carrier\n * that moves the encoded envelopes verbatim satisfies this service. Implementations MUST\n * surface every delivery problem as `PortTransportError` and must never fabricate an answer.\n */\nexport class ThreadPortTransport extends Context.Service<\n ThreadPortTransport,\n {\n readonly call: (\n threadId: ThreadId,\n request: PortRequestEnvelope,\n ) => Effect.Effect<unknown, PortTransportError>;\n }\n>()(\"@effect-agent/storage-cloudflare/ThreadPortTransport\") {}\n\n/** Construction options shared by both routed port Layers. */\nexport interface RoutedPortOptions {\n /**\n * The Thread this Durable Object owns (the Object identity rule is\n * `namespace.idFromName(threadId)`). Requests addressed here execute on the local\n * facet; requests addressed anywhere else route through the transport or fail fast typed.\n */\n readonly localThreadId: ThreadId;\n}\n\n/** Where one port request must execute. */\ntype RouteTarget =\n | { readonly _tag: \"local\" }\n | { readonly _tag: \"foreign\"; readonly threadId: ThreadId };\n\nconst LOCAL: RouteTarget = { _tag: \"local\" };\n\n/**\n * Parse a DC-minted routable Submission identity — `{uuidv7}:{threadId}`, split at the\n * FIRST `:` because the Thread tail may itself contain colons (D-P6-5). This adapter\n * minted the format at admission and is the ONLY component that parses it; identities that do\n * not carry the minted shape (no separator, non-UUID head, empty tail) fall back to the local\n * facet, which is the only authority this Object can consult without inventing an owner.\n * Identities beyond the ledger's 1,024-character row bound fail typed: the minting side\n * refused them at admission, so they cannot name any stored row anywhere.\n */\nconst routableSubmissionTarget = (\n localThreadId: ThreadId,\n): ((operation: string, submissionId: string) => Effect.Effect<RouteTarget, LedgerError>) =>\n Effect.fn(\"DoPortRouting.routableSubmissionTarget\")(function* (\n operation: string,\n submissionId: string,\n ): Effect.fn.Return<RouteTarget, LedgerError> {\n if (submissionId.length > MAX_ROUTABLE_SUBMISSION_ID_LENGTH) {\n return yield* LedgerError.make({\n operation,\n message:\n `A Submission identity of ${submissionId.length} characters exceeds the ` +\n `${MAX_ROUTABLE_SUBMISSION_ID_LENGTH}-character routable identity bound; admission ` +\n \"refuses such identities, so it cannot name any stored row.\",\n });\n }\n const separator = submissionId.indexOf(\":\");\n\n if (separator === -1) return LOCAL;\n if (!UUID_HEAD_PATTERN.test(submissionId.slice(0, separator))) return LOCAL;\n const tail = submissionId.slice(separator + 1);\n\n if (tail === localThreadId) return LOCAL;\n\n return yield* decodeThreadId(tail).pipe(\n Effect.map((threadId): RouteTarget => ({ _tag: \"foreign\", threadId })),\n Effect.orElseSucceed(() => LOCAL),\n );\n });\n\nconst NoAdditionalPortFailure = Schema.Never;\nconst AbortPortFailure = Schema.Union([SettlementConflict, JoinedToHost]);\nconst AppendPortFailure = Schema.Union([ThreadNotMaterialized, AppendConflict, FenceRejected]);\n\n/**\n * The fail-fast refusal for any foreign operation OUTSIDE the closed route-capable subset\n * (plan §1.3): honesty over accidental distribution.\n */\nconst crossThreadLedgerError = (operation: string, target: string): LedgerError =>\n LedgerError.make({\n operation,\n message:\n `${operation} addressed to foreign Thread ${target} is not route-capable; the ` +\n \"closed cross-Object subset is admit, markReady, lookup, resolveAdmission, \" +\n \"requestAbort, and recordChildSettled. Every other ledger operation is lane-local by \" +\n \"construction and must execute inside the owning Thread's Durable Object.\",\n });\n\nconst crossThreadStoreError = (operation: string, target: string): ThreadStoreError =>\n ThreadStoreError.make({\n operation,\n message:\n `${operation} addressed to foreign Thread ${target} is not route-capable; the ` +\n \"closed cross-Object subset is materialize, append, read (paged), inspectTail, and \" +\n \"export. Observation and checkpoints are lane-local by construction and must execute \" +\n \"inside the owning Thread's Durable Object.\",\n });\n\nconst makeTransportCall = (transport: ThreadPortTransport[\"Service\"]) =>\n Effect.fn(\"DoPortRouting.transportCall\")(function* (target: ThreadId, call: PortRequest) {\n const encoded = yield* encodePortRequest(call).pipe(\n Effect.mapError((error) =>\n PortProtocolError.make({\n message: boundPortDiagnostic(`The port request could not be encoded: ${error.message}`),\n }),\n ),\n );\n\n const raw = yield* transport.call(target, encoded);\n\n return yield* decodePortResponse(raw).pipe(\n Effect.mapError((error) =>\n PortProtocolError.make({\n message: boundPortDiagnostic(`The port response could not be decoded: ${error.message}`),\n }),\n ),\n );\n });\n\ntype TransportCall = ReturnType<typeof makeTransportCall>;\n\nconst makeRoutedLedgerServices = Effect.fn(\"DoPortRouting.makeRoutedLedgerServices\")(function* (\n options: RoutedPortOptions,\n) {\n const local = yield* SubmissionLedger;\n const transport = yield* ThreadPortTransport;\n const transportCall: TransportCall = makeTransportCall(transport);\n const submissionTarget = routableSubmissionTarget(options.localThreadId);\n\n const routeFailure =\n (operation: string, target: string) =>\n (error: PortTransportError | PortProtocolError): LedgerError =>\n LedgerError.make({\n operation,\n message: boundPortDiagnostic(\n `Routed ${operation} to the Thread Object owning ${target} failed: ${error.message}`,\n ),\n cause: error,\n });\n\n /**\n * One routed ledger call: encode, deliver, decode, then narrow the uniform envelope to the\n * operation's own result and failure surface. A foreign `LedgerError` is always in-channel;\n * any failure outside the operation's declared surface — including protocol anomalies — is\n * folded into a `LedgerError` naming the anomaly instead of being erased or re-thrown raw.\n */\n const foreignLedgerCall = <ResultSchema extends Schema.Top, FailureSchema extends Schema.Top>(\n operation: string,\n target: ThreadId,\n call: PortRequest,\n resultSchema: ResultSchema,\n failureSchema: FailureSchema,\n ): Effect.Effect<ResultSchema[\"Type\"], FailureSchema[\"Type\"] | LedgerError> => {\n const isExpectedResult = Schema.is(resultSchema);\n const isExpectedFailure = Schema.is(failureSchema);\n\n return transportCall(target, call).pipe(\n Effect.mapError(routeFailure(operation, target)),\n Effect.flatMap(\n (response): Effect.Effect<ResultSchema[\"Type\"], FailureSchema[\"Type\"] | LedgerError> => {\n if (response._tag === \"PortFailed\") {\n const failure = response.failure;\n\n if (isExpectedFailure(failure)) return Effect.fail(failure);\n if (failure._tag === \"LedgerError\") return Effect.fail(failure);\n\n return Effect.fail(\n LedgerError.make({\n operation,\n message: boundPortDiagnostic(\n `The Thread Object owning ${target} answered ${operation} with the ` +\n `out-of-contract failure ${failure._tag}: ${failure.message}`,\n ),\n cause: failure,\n }),\n );\n }\n const result = response.result;\n\n if (!isExpectedResult(result)) {\n return Effect.fail(\n LedgerError.make({\n operation,\n message:\n `The Thread Object owning ${target} answered ${operation} with the ` +\n `mismatched result ${result._tag}.`,\n }),\n );\n }\n\n return Effect.succeed(result);\n },\n ),\n Effect.withSpan(\"DoPortRouting.foreignLedgerCall\", {\n attributes: { operation, target },\n }),\n );\n };\n\n /**\n * Routed `resolveAdmission` — where the S2 tri-state becomes real (plan §1.3): when the\n * owning Object cannot be reached, or its answer cannot be understood, the routed adapter\n * answers `AdmissionIndeterminate{reason}` and NEVER `NotAdmitted` — an unreachable\n * authority proves nothing, and only `NotAdmitted` permits an admission attempt (SUB-031).\n * A typed `LedgerError` answered BY the authority still fails typed: the authority was\n * reached and reported its own storage failure.\n */\n const resolveForeignAdmission = (\n target: ThreadId,\n request: SubmissionLookupByKey,\n ): Effect.Effect<\n | AdmissionIndeterminate\n | Extract<PortResult, { readonly _tag: \"LedgerResolveAdmissionResult\" }>[\"resolution\"],\n LedgerError\n > =>\n transportCall(target, LedgerResolveAdmissionCall.make({ request })).pipe(\n Effect.flatMap((response) => {\n if (response._tag === \"PortFailed\") {\n if (response.failure._tag === \"LedgerError\") return Effect.fail(response.failure);\n\n return Effect.succeed(\n AdmissionIndeterminate.make({\n reason: boundPortDiagnostic(\n `The Thread Object owning ${target} answered resolveAdmission with the ` +\n `out-of-contract failure ${response.failure._tag}: ${response.failure.message}`,\n ),\n }),\n );\n }\n if (response.result._tag !== \"LedgerResolveAdmissionResult\") {\n return Effect.succeed(\n AdmissionIndeterminate.make({\n reason: boundPortDiagnostic(\n `The Thread Object owning ${target} answered resolveAdmission with the ` +\n `mismatched result ${response.result._tag}.`,\n ),\n }),\n );\n }\n\n return Effect.succeed(response.result.resolution);\n }),\n Effect.catchTags({\n PortTransportError: (error) =>\n Effect.succeed(\n AdmissionIndeterminate.make({\n reason: boundPortDiagnostic(\n `The Thread Object owning ${target} is unreachable: ${error.message}`,\n ),\n }),\n ),\n PortProtocolError: (error) =>\n Effect.succeed(\n AdmissionIndeterminate.make({\n reason: boundPortDiagnostic(\n `The answer of the Thread Object owning ${target} could not be ` +\n `understood: ${error.message}`,\n ),\n }),\n ),\n }),\n Effect.withSpan(\"DoPortRouting.resolveForeignAdmission\", { attributes: { target } }),\n );\n\n const foreignLookupById = (\n operation: string,\n target: ThreadId,\n submissionId: SubmissionId,\n ): Effect.Effect<Option.Option<SubmissionSnapshot>, LedgerError> =>\n foreignLedgerCall(\n operation,\n target,\n LedgerLookupCall.make({ request: SubmissionLookupById.make({ submissionId }) }),\n LedgerLookupResult,\n NoAdditionalPortFailure,\n ).pipe(\n Effect.map((result) =>\n result.submission === undefined ? Option.none() : Option.some(result.submission),\n ),\n );\n\n /**\n * Enrich a LOCAL parent's recovery snapshot with the lane state of attached children whose\n * rows live in other Durable Objects (plan §1.3): markers first (the local facet already\n * consulted them), then a routed per-child `lookup` for any attached child that is neither\n * local nor marker-settled. A transport failure surfaces as `LedgerError` so the alarm\n * pass retries; the child's canonical Settlement remains the only authority (DUR-015).\n */\n const enrichChildAttachments = Effect.fn(\"DoPortRouting.enrichChildAttachments\")(function* (\n snapshot: RecoverySnapshot,\n ): Effect.fn.Return<RecoverySnapshot, LedgerError> {\n const operation = \"ledger load recovery snapshot\";\n\n const attachments = new Map(\n snapshot.childAttachments.map((attachment) => [attachment.childSubmissionId, attachment]),\n );\n\n let enriched = false;\n\n for (const reservation of snapshot.childReservations) {\n const childSubmissionId = reservation.childSubmissionId;\n\n if (childSubmissionId === undefined || attachments.has(childSubmissionId)) continue;\n const target = yield* submissionTarget(operation, childSubmissionId);\n\n // A local or opaque child identity was already answered authoritatively by the local\n // facet; absence there means the child admission never committed.\n if (target._tag !== \"foreign\") continue;\n const child = yield* foreignLookupById(operation, target.threadId, childSubmissionId);\n\n if (Option.isNone(child)) continue;\n attachments.set(\n childSubmissionId,\n ChildAttachmentSnapshot.make({\n toolCallId: reservation.parentToolCallId,\n childSubmissionId,\n childState: child.value.state,\n ...(child.value.settledOutcome === undefined\n ? {}\n : { childOutcome: child.value.settledOutcome }),\n }),\n );\n enriched = true;\n }\n if (!enriched) return snapshot;\n // Rebuild in reservation (parent Tool Call) order, the order the local facet documents.\n const ordered: Array<ChildAttachmentSnapshot> = [];\n\n for (const reservation of snapshot.childReservations) {\n if (reservation.childSubmissionId === undefined) continue;\n const attachment = attachments.get(reservation.childSubmissionId);\n\n if (attachment !== undefined) ordered.push(attachment);\n }\n\n return RecoverySnapshot.make({ ...snapshot, childAttachments: ordered });\n });\n\n const routed = SubmissionLedger.of({\n capabilities: local.capabilities,\n\n admit: (request) =>\n request.threadId === options.localThreadId\n ? local.admit(request)\n : foreignLedgerCall(\n \"ledger admit\",\n request.threadId,\n LedgerAdmitCall.make({ request }),\n LedgerAdmitResult,\n Schema.Union([AdmissionConflict, AdmissionPolicyError]),\n ).pipe(Effect.map((reply) => reply.result)),\n\n markReady: (request) =>\n submissionTarget(\"ledger mark ready\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.markReady(request)\n : foreignLedgerCall(\n \"ledger mark ready\",\n target.threadId,\n LedgerMarkReadyCall.make({ request }),\n LedgerMarkReadyResult,\n NoAdditionalPortFailure,\n ).pipe(Effect.asVoid),\n ),\n ),\n\n lookup: (request) =>\n request._tag === \"SubmissionLookupById\"\n ? submissionTarget(\"ledger lookup\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.lookup(request)\n : foreignLookupById(\"ledger lookup\", target.threadId, request.submissionId),\n ),\n )\n : request.threadId === options.localThreadId\n ? local.lookup(request)\n : foreignLedgerCall(\n \"ledger lookup\",\n request.threadId,\n LedgerLookupCall.make({ request }),\n LedgerLookupResult,\n NoAdditionalPortFailure,\n ).pipe(\n Effect.map((result) =>\n result.submission === undefined ? Option.none() : Option.some(result.submission),\n ),\n ),\n\n resolveAdmission: (request) =>\n request.threadId === options.localThreadId\n ? local.resolveAdmission(request)\n : resolveForeignAdmission(request.threadId, request),\n\n requestAbort: (request) =>\n submissionTarget(\"ledger request abort\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.requestAbort(request)\n : foreignLedgerCall(\n \"ledger request abort\",\n target.threadId,\n LedgerRequestAbortCall.make({ request }),\n LedgerRequestAbortResult,\n AbortPortFailure,\n ).pipe(Effect.map((reply) => reply.intent)),\n ),\n ),\n\n recordChildSettled: (request) =>\n submissionTarget(\"ledger record child settled\", request.parentSubmissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.recordChildSettled(request)\n : foreignLedgerCall(\n \"ledger record child settled\",\n target.threadId,\n LedgerRecordChildSettledCall.make({ request }),\n LedgerRecordChildSettledResult,\n NoAdditionalPortFailure,\n ).pipe(Effect.map((reply) => reply.outcome)),\n ),\n ),\n\n // Every operation below is lane-local by construction (plan §1.3): a foreign address is\n // an out-of-contract call and fails fast typed instead of being quietly distributed.\n claim: (request) =>\n request.threadId === options.localThreadId\n ? local.claim(request)\n : Effect.fail(crossThreadLedgerError(\"ledger claim\", request.threadId)),\n\n claimJoining: (request) =>\n request.threadId === options.localThreadId\n ? local.claimJoining(request)\n : Effect.fail(crossThreadLedgerError(\"ledger claim joining\", request.threadId)),\n\n renewOwnership: (request) =>\n submissionTarget(\"ledger renew ownership\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.renewOwnership(request)\n : Effect.fail(crossThreadLedgerError(\"ledger renew ownership\", target.threadId)),\n ),\n ),\n\n releaseOwnership: (request) =>\n submissionTarget(\"ledger release ownership\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.releaseOwnership(request)\n : Effect.fail(crossThreadLedgerError(\"ledger release ownership\", target.threadId)),\n ),\n ),\n\n markInputApplied: (request) =>\n submissionTarget(\"ledger mark input applied\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.markInputApplied(request)\n : Effect.fail(crossThreadLedgerError(\"ledger mark input applied\", target.threadId)),\n ),\n ),\n\n reserveSettlement: (request) =>\n submissionTarget(\"ledger reserve settlement\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.reserveSettlement(request)\n : Effect.fail(crossThreadLedgerError(\"ledger reserve settlement\", target.threadId)),\n ),\n ),\n\n finalizeSettlement: (request) =>\n submissionTarget(\"ledger finalize settlement\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.finalizeSettlement(request)\n : Effect.fail(crossThreadLedgerError(\"ledger finalize settlement\", target.threadId)),\n ),\n ),\n\n markJoined: (request) =>\n submissionTarget(\"ledger mark joined\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.markJoined(request)\n : Effect.fail(crossThreadLedgerError(\"ledger mark joined\", target.threadId)),\n ),\n ),\n\n revertJoining: (request) =>\n submissionTarget(\"ledger revert joining\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.revertJoining(request)\n : Effect.fail(crossThreadLedgerError(\"ledger revert joining\", target.threadId)),\n ),\n ),\n\n suspend: (request) =>\n submissionTarget(\"ledger suspend\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.suspend(request)\n : Effect.fail(crossThreadLedgerError(\"ledger suspend\", target.threadId)),\n ),\n ),\n\n recordApprovalDecision: (command) =>\n submissionTarget(\"ledger record approval decision\", command.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.recordApprovalDecision(command)\n : Effect.fail(\n crossThreadLedgerError(\"ledger record approval decision\", target.threadId),\n ),\n ),\n ),\n\n markUnknown: (request) =>\n submissionTarget(\"ledger mark unknown\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.markUnknown(request)\n : Effect.fail(crossThreadLedgerError(\"ledger mark unknown\", target.threadId)),\n ),\n ),\n\n recordUnknownResolution: (command) =>\n submissionTarget(\"ledger record unknown resolution\", command.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.recordUnknownResolution(command)\n : Effect.fail(\n crossThreadLedgerError(\"ledger record unknown resolution\", target.threadId),\n ),\n ),\n ),\n\n reserveChildBudget: (request) =>\n submissionTarget(\"ledger reserve child budget\", request.parentSubmissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.reserveChildBudget(request)\n : Effect.fail(crossThreadLedgerError(\"ledger reserve child budget\", target.threadId)),\n ),\n ),\n\n // Reservation identities carry no Thread address; the reservation row lives in the\n // parent's own Object and these transitions are parent-lane-local by construction, so\n // they always execute on the local facet (which fails typed for an unknown row).\n attachChildToReservation: local.attachChildToReservation,\n beginChildBudgetRelease: local.beginChildBudgetRelease,\n releaseChildBudget: local.releaseChildBudget,\n\n // The local scan IS the whole worklist: one Thread per Object (durability §5).\n scanNonterminal: local.scanNonterminal,\n\n readAbortIntent: (request) =>\n submissionTarget(\"ledger read abort intent\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.readAbortIntent(request)\n : Effect.fail(crossThreadLedgerError(\"ledger read abort intent\", target.threadId)),\n ),\n ),\n\n loadRecoverySnapshot: (request) =>\n submissionTarget(\"ledger load recovery snapshot\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.loadRecoverySnapshot(request).pipe(Effect.flatMap(enrichChildAttachments))\n : Effect.fail(crossThreadLedgerError(\"ledger load recovery snapshot\", target.threadId)),\n ),\n ),\n });\n\n return Context.make(SubmissionLedger, routed);\n});\n\nconst makeRoutedStoreServices = Effect.fn(\"DoPortRouting.makeRoutedStoreServices\")(function* (\n options: RoutedPortOptions,\n) {\n const local = yield* ThreadStore;\n const checkpoints = local.checkpoints;\n const recoveryCheckpoints = local.recoveryCheckpoints;\n const transport = yield* ThreadPortTransport;\n const transportCall: TransportCall = makeTransportCall(transport);\n\n const routeFailure =\n (operation: string, target: string) =>\n (error: PortTransportError | PortProtocolError): ThreadStoreError =>\n ThreadStoreError.make({\n operation,\n message: boundPortDiagnostic(\n `Routed ${operation} to the Thread Object owning ${target} failed: ${error.message}`,\n ),\n cause: error,\n });\n\n /** The store twin of `foreignLedgerCall` with `ThreadStoreError` as the base error. */\n const foreignStoreCall = <ResultSchema extends Schema.Top, FailureSchema extends Schema.Top>(\n operation: string,\n target: ThreadId,\n call: PortRequest,\n resultSchema: ResultSchema,\n failureSchema: FailureSchema,\n ): Effect.Effect<ResultSchema[\"Type\"], FailureSchema[\"Type\"] | ThreadStoreError> => {\n const isExpectedResult = Schema.is(resultSchema);\n const isExpectedFailure = Schema.is(failureSchema);\n\n return transportCall(target, call).pipe(\n Effect.mapError(routeFailure(operation, target)),\n Effect.flatMap(\n (\n response,\n ): Effect.Effect<ResultSchema[\"Type\"], FailureSchema[\"Type\"] | ThreadStoreError> => {\n if (response._tag === \"PortFailed\") {\n const failure = response.failure;\n\n if (isExpectedFailure(failure)) return Effect.fail(failure);\n if (failure._tag === \"ThreadStoreError\") return Effect.fail(failure);\n\n return Effect.fail(\n ThreadStoreError.make({\n operation,\n message: boundPortDiagnostic(\n `The Thread Object owning ${target} answered ${operation} with the ` +\n `out-of-contract failure ${failure._tag}: ${failure.message}`,\n ),\n cause: failure,\n }),\n );\n }\n const result = response.result;\n\n if (!isExpectedResult(result)) {\n return Effect.fail(\n ThreadStoreError.make({\n operation,\n message:\n `The Thread Object owning ${target} answered ${operation} with the ` +\n `mismatched result ${result._tag}.`,\n }),\n );\n }\n\n return Effect.succeed(result);\n },\n ),\n Effect.withSpan(\"DoPortRouting.foreignStoreCall\", {\n attributes: { operation, target },\n }),\n );\n };\n\n const routed = ThreadStore.of({\n materialize: (request) =>\n request.threadId === options.localThreadId\n ? local.materialize(request)\n : foreignStoreCall(\n \"thread materialize\",\n request.threadId,\n StoreMaterializeCall.make({ request }),\n StoreMaterializeResult,\n FenceRejected,\n ).pipe(Effect.asVoid),\n\n append: (request) =>\n request.threadId === options.localThreadId\n ? local.append(request)\n : foreignStoreCall(\n \"thread append\",\n request.threadId,\n StoreAppendCall.make({ request }),\n StoreAppendResult,\n AppendPortFailure,\n ).pipe(Effect.map((reply) => reply.result)),\n\n read: (request) =>\n request.threadId === options.localThreadId\n ? local.read(request)\n : Stream.unwrap(\n foreignStoreCall(\n \"thread read\",\n request.threadId,\n StoreReadPageCall.make({ request }),\n StoreReadPageResult,\n ThreadNotMaterialized,\n ).pipe(Effect.map((reply) => Stream.fromIterable(reply.records))),\n ),\n\n inspectTail: (request) =>\n request.threadId === options.localThreadId\n ? local.inspectTail(request)\n : foreignStoreCall(\n \"thread inspect tail\",\n request.threadId,\n StoreInspectTailCall.make({ request }),\n StoreInspectTailResult,\n ThreadNotMaterialized,\n ).pipe(Effect.map((reply) => reply.tail)),\n\n export: (request) =>\n request.threadId === options.localThreadId\n ? local.export(request)\n : foreignStoreCall(\n \"thread export\",\n request.threadId,\n StoreExportCall.make({ request }),\n StoreExportResult,\n ThreadNotMaterialized,\n ).pipe(Effect.map((reply) => reply.export)),\n\n // Observation and checkpoints are lane-local: the closed route-capable store subset\n // is materialize/append/read/inspectTail/export. Recovery cache misses can fall back\n // to those canonical reads, including when the cache belongs to a foreign Object.\n observe: (request) =>\n request.threadId === options.localThreadId\n ? local.observe(request)\n : Stream.unwrap(Effect.fail(crossThreadStoreError(\"thread observe\", request.threadId))),\n\n ...(recoveryCheckpoints === undefined\n ? {}\n : {\n recoveryCheckpoints: {\n save: (request) =>\n request.checkpoint.threadId === options.localThreadId\n ? recoveryCheckpoints.save(request)\n : Effect.fail(\n crossThreadStoreError(\n \"thread save recovery checkpoint\",\n request.checkpoint.threadId,\n ),\n ),\n load: (request) =>\n request.threadId === options.localThreadId\n ? recoveryCheckpoints.load(request)\n : Effect.succeed(Option.none()),\n },\n }),\n ...(checkpoints === undefined\n ? {}\n : {\n checkpoints: {\n save: (request) =>\n request.checkpoint.threadId === options.localThreadId\n ? checkpoints.save(request)\n : Effect.fail(\n crossThreadStoreError(\"thread save checkpoint\", request.checkpoint.threadId),\n ),\n load: (request) =>\n request.threadId === options.localThreadId\n ? checkpoints.load(request)\n : Effect.fail(crossThreadStoreError(\"thread load checkpoint\", request.threadId)),\n },\n }),\n });\n\n return Context.make(ThreadStore, routed);\n});\n\n/**\n * Routing decorator over the LOCAL `SubmissionLedger` facet (plan §1.3): a request addressing\n * this Object's Thread executes locally; a route-capable request addressing another\n * Thread is Schema-encoded onto the `ThreadPortTransport` and executed by the\n * owning Object's local facet; any other foreign request fails fast typed. Provide the WP1\n * local facet (`submissionLedgerLayer`/`ledgerLayer`) and a transport to close it.\n */\nexport const routedSubmissionLedgerLayer = (\n options: RoutedPortOptions,\n): Layer.Layer<SubmissionLedger, never, SubmissionLedger | ThreadPortTransport> =>\n Layer.effectContext(makeRoutedLedgerServices(options));\n\n/**\n * Routing decorator over the LOCAL `ThreadStore` facet (plan §1.3): this-thread\n * requests execute locally; foreign materialize/append/read/inspectTail/export travel the\n * transport. Foreign recovery-cache loads return none for canonical replay; other foreign\n * checkpoint operations and observation fail fast typed.\n */\nexport const routedThreadStoreLayer = (\n options: RoutedPortOptions,\n): Layer.Layer<ThreadStore, never, ThreadStore | ThreadPortTransport> =>\n Layer.effectContext(makeRoutedStoreServices(options));\n\n// ---------------------------------------------------------------------------\n// Owner-side execution\n// ---------------------------------------------------------------------------\n\n/** Fold one port operation's typed failures into the uniform response envelope. */\nconst capture = <Failure extends PortFailure>(\n effect: Effect.Effect<PortResult, Failure>,\n): Effect.Effect<PortResponse> =>\n effect.pipe(\n Effect.map((result): PortResponse => PortSucceeded.make({ result })),\n Effect.catch((failure) => Effect.succeed<PortResponse>(PortFailed.make({ failure }))),\n );\n\n/**\n * Execute one decoded port request against THIS Object's LOCAL facets — the owner-side half\n * of the routed ports (plan §1.3). Callers must provide the WP1 local facets, never the\n * routed decorators: the routing layer already established that this Object owns the\n * addressed Thread, and re-routing here could bounce a request between Objects.\n * Failures never escape — every typed port failure becomes a `PortFailed` envelope that\n * re-decodes on the caller side.\n */\nexport const executePortRequest = Effect.fn(\"DoPortRouting.executePortRequest\")(function* (\n request: PortRequest,\n): Effect.fn.Return<PortResponse, never, SubmissionLedger | ThreadStore> {\n switch (request._tag) {\n case \"LedgerAdmit\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .admit(request.request)\n .pipe(Effect.map((result) => LedgerAdmitResult.make({ result }))),\n );\n }\n case \"LedgerMarkReady\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger.markReady(request.request).pipe(Effect.map(() => LedgerMarkReadyResult.make({}))),\n );\n }\n case \"LedgerLookup\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .lookup(request.request)\n .pipe(\n Effect.map((submission) =>\n Option.isSome(submission)\n ? LedgerLookupResult.make({ submission: submission.value })\n : LedgerLookupResult.make({}),\n ),\n ),\n );\n }\n case \"LedgerResolveAdmission\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .resolveAdmission(request.request)\n .pipe(Effect.map((resolution) => LedgerResolveAdmissionResult.make({ resolution }))),\n );\n }\n case \"LedgerRequestAbort\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .requestAbort(request.request)\n .pipe(Effect.map((intent) => LedgerRequestAbortResult.make({ intent }))),\n );\n }\n case \"LedgerRecordChildSettled\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .recordChildSettled(request.request)\n .pipe(Effect.map((outcome) => LedgerRecordChildSettledResult.make({ outcome }))),\n );\n }\n case \"StoreMaterialize\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store.materialize(request.request).pipe(Effect.map(() => StoreMaterializeResult.make({}))),\n );\n }\n case \"StoreAppend\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store\n .append(request.request)\n .pipe(Effect.map((result) => StoreAppendResult.make({ result }))),\n );\n }\n case \"StoreReadPage\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store.read(request.request).pipe(\n Stream.runCollect,\n Effect.map((records) => StoreReadPageResult.make({ records: [...records] })),\n ),\n );\n }\n case \"StoreInspectTail\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store\n .inspectTail(request.request)\n .pipe(Effect.map((tail) => StoreInspectTailResult.make({ tail }))),\n );\n }\n case \"StoreExport\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store\n .export(request.request)\n .pipe(Effect.map((threadExport) => StoreExportResult.make({ export: threadExport }))),\n );\n }\n }\n});\n\n/**\n * The last-resort wire fallback when even encoding a response fails: the literal encoded\n * form of `PortFailed(PortProtocolError)` — tagged classes of bounded strings encode to\n * exactly this shape, so no Schema round trip is needed to produce it.\n */\nconst encodedProtocolFailure = (message: string): unknown => ({\n _tag: \"PortFailed\",\n failure: { _tag: \"PortProtocolError\", message: boundPortDiagnostic(message) },\n});\n\n/**\n * The complete owner-side endpoint body for `portCall` (D-P6-3): decode the wire request,\n * execute it against this Object's LOCAL facets, and answer with the encoded response\n * envelope. Total by construction — a request that cannot be decoded, or a response that\n * cannot be encoded, answers `PortFailed(PortProtocolError)` instead of throwing, so the\n * transport never has to interpret exceptions as protocol answers.\n */\nexport const handleEncodedPortRequest = Effect.fn(\"DoPortRouting.handleEncodedPortRequest\")(\n function* (encoded: unknown): Effect.fn.Return<unknown, never, SubmissionLedger | ThreadStore> {\n const response = yield* decodePortRequest(encoded).pipe(\n Effect.flatMap(executePortRequest),\n Effect.catch((error) =>\n Effect.succeed<PortResponse>(\n PortFailed.make({\n failure: PortProtocolError.make({\n message: boundPortDiagnostic(\n `The port request could not be decoded: ${error.message}`,\n ),\n }),\n }),\n ),\n ),\n );\n\n return yield* encodePortResponse(response).pipe(\n Effect.catch((error) =>\n Effect.succeed(\n encodedProtocolFailure(`The port response could not be encoded: ${error.message}`),\n ),\n ),\n );\n },\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"PortRouting.mjs","names":[],"sources":["../src/PortRouting.ts"],"sourcesContent":["import {\n AdmissionIndeterminate,\n AdmissionConflict,\n AdmissionPolicyError,\n ChildAttachmentSnapshot,\n JoinedToHost,\n LedgerError,\n RecoverySnapshot,\n SettlementConflict,\n SubmissionLedger,\n SubmissionLookupById,\n type SubmissionLookupByKey,\n type SubmissionSnapshot,\n} from \"@effect-agent/thread/SubmissionLedger\";\nimport {\n AppendConflict,\n ThreadMaterialization,\n ThreadNotMaterialized,\n ThreadStore,\n ThreadStoreError,\n FenceRejected,\n} from \"@effect-agent/thread/ThreadStore\";\nimport { Context, Effect, Layer, Option, Predicate, Schema, Stream } from \"effect\";\n\nimport {\n boundPortDiagnostic,\n decodePortRequest,\n decodePortResponse,\n encodePortRequest,\n encodePortResponse,\n LedgerAdmitCall,\n LedgerAdmitResult,\n LedgerLookupCall,\n LedgerLookupResult,\n LedgerMarkReadyCall,\n LedgerMarkReadyResult,\n LedgerRecordChildSettledCall,\n LedgerRecordChildSettledResult,\n LedgerRequestAbortCall,\n LedgerRequestAbortResult,\n LedgerResolveAdmissionCall,\n LedgerResolveAdmissionResult,\n PortFailed,\n PortProtocolError,\n PortSucceeded,\n StoreAppendCall,\n StoreAppendResult,\n StoreExportCall,\n StoreExportResult,\n StoreInspectTailCall,\n StoreInspectTailResult,\n StoreMaterializeCall,\n StoreMaterializeResult,\n StoreReadPageCall,\n StoreReadPageResult,\n type PortFailure,\n type PortRequest,\n type PortRequestEnvelope,\n type PortResponse,\n type PortResult,\n} from \"./PortProtocol.ts\";\n\ntype ThreadId = ThreadMaterialization[\"threadId\"];\ntype SubmissionId = SubmissionSnapshot[\"submissionId\"];\n\nconst ThreadIdSchema = ThreadMaterialization.fields.threadId;\nconst decodeThreadId = Schema.decodeUnknownEffect(ThreadIdSchema);\n\n/**\n * The ledger row bound routable Submission identities must respect (mirrors the local\n * facet's `MAX_IDENTIFIER_LENGTH`; the minting side already refuses longer identities typed\n * at admission, so a longer identity presented here cannot name any stored row).\n */\nconst MAX_ROUTABLE_SUBMISSION_ID_LENGTH = 1_024;\n\n/** The `{uuidv7}` head of a DC-minted routable Submission identity. */\nconst UUID_HEAD_PATTERN =\n /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;\n\n/**\n * A transport could not deliver a port request to (or an answer from) the owning\n * Thread's Durable Object. `retryable` carries the platform's own stub signal when one\n * exists. This error never crosses the wire — it is the CALLER-side evidence that the\n * authority was unreachable, which is exactly the case `AdmissionIndeterminate` was\n * specified for (SUB-031).\n */\nexport class PortTransportError extends Schema.TaggedError<PortTransportError>()(\n \"PortTransportError\",\n {\n target: Schema.String,\n message: Schema.String,\n retryable: Schema.optionalKey(Schema.Boolean),\n cause: Schema.optionalKey(Schema.Defect()),\n },\n) {}\n\nconst safeTransportDiagnostic = (cause: unknown): string => {\n try {\n const message = cause instanceof Error ? cause.message : cause;\n\n return boundPortDiagnostic(typeof message === \"string\" ? message : String(message));\n } catch {\n return \"[unavailable transport diagnostic]\";\n }\n};\n\nconst transportRetryableSignal = (cause: unknown): boolean | undefined => {\n if (!Predicate.isObjectKeyword(cause)) return undefined;\n try {\n const signal = Reflect.get(cause, \"retryable\");\n\n return typeof signal === \"boolean\" ? signal : undefined;\n } catch {\n return undefined;\n }\n};\n\n/**\n * Build a `PortTransportError` from an arbitrary thrown transport cause, preserving the\n * platform stub's own `retryable` signal when present.\n */\nexport const portTransportFailure = (target: string, cause: unknown): PortTransportError => {\n const retryable = transportRetryableSignal(cause);\n\n return PortTransportError.make({\n target,\n message: safeTransportDiagnostic(cause),\n ...(retryable === undefined ? {} : { retryable }),\n cause,\n });\n};\n\n/**\n * Delivery of Schema-encoded port envelopes to the Durable Object that owns a FOREIGN\n * Thread (plan §1.3, D-P6-3). The shipped implementation (platform-cloudflare, WP3)\n * calls the owner's `portCall` over native Durable Object JS RPC via\n * `namespace.idFromName(threadId)`; the protocol is transport-agnostic and any carrier\n * that moves the encoded envelopes verbatim satisfies this service. Implementations MUST\n * surface every delivery problem as `PortTransportError` and must never fabricate an answer.\n */\nexport class ThreadPortTransport extends Context.Service<\n ThreadPortTransport,\n {\n readonly call: (\n threadId: ThreadId,\n request: PortRequestEnvelope,\n ) => Effect.Effect<unknown, PortTransportError>;\n }\n>()(\"@effect-agent/storage-cloudflare/ThreadPortTransport\") {}\n\n/** Construction options shared by both routed port Layers. */\nexport interface RoutedPortOptions {\n /**\n * Decide whether this physical owner stores the addressed logical Thread. Local\n * requests use the same SQLite facets; foreign requests use the transport or fail\n * fast typed. The predicate determines placement, never caller authorization.\n */\n readonly ownsThread: (threadId: ThreadId) => boolean;\n}\n\n/** Where one port request must execute. */\ntype RouteTarget =\n | { readonly _tag: \"local\" }\n | { readonly _tag: \"foreign\"; readonly threadId: ThreadId };\n\nconst LOCAL: RouteTarget = { _tag: \"local\" };\n\n/**\n * Parse a DC-minted routable Submission identity — `{uuidv7}:{threadId}`, split at the\n * FIRST `:` because the Thread tail may itself contain colons (D-P6-5). This adapter\n * minted the format at admission and is the ONLY component that parses it; identities that do\n * not carry the minted shape (no separator, non-UUID head, empty tail) fall back to the local\n * facet, which is the only authority this Object can consult without inventing an owner.\n * Identities beyond the ledger's 1,024-character row bound fail typed: the minting side\n * refused them at admission, so they cannot name any stored row anywhere.\n */\nconst routableSubmissionTarget = (\n ownsThread: RoutedPortOptions[\"ownsThread\"],\n): ((operation: string, submissionId: string) => Effect.Effect<RouteTarget, LedgerError>) =>\n Effect.fn(\"DoPortRouting.routableSubmissionTarget\")(function* (\n operation: string,\n submissionId: string,\n ): Effect.fn.Return<RouteTarget, LedgerError> {\n if (submissionId.length > MAX_ROUTABLE_SUBMISSION_ID_LENGTH) {\n return yield* LedgerError.make({\n operation,\n message:\n `A Submission identity of ${submissionId.length} characters exceeds the ` +\n `${MAX_ROUTABLE_SUBMISSION_ID_LENGTH}-character routable identity bound; admission ` +\n \"refuses such identities, so it cannot name any stored row.\",\n });\n }\n const separator = submissionId.indexOf(\":\");\n\n if (separator === -1) return LOCAL;\n if (!UUID_HEAD_PATTERN.test(submissionId.slice(0, separator))) return LOCAL;\n const tail = submissionId.slice(separator + 1);\n\n return yield* decodeThreadId(tail).pipe(\n Effect.map((threadId): RouteTarget =>\n ownsThread(threadId) ? LOCAL : { _tag: \"foreign\", threadId },\n ),\n Effect.orElseSucceed(() => LOCAL),\n );\n });\n\nconst NoAdditionalPortFailure = Schema.Never;\nconst AbortPortFailure = Schema.Union([SettlementConflict, JoinedToHost]);\nconst AppendPortFailure = Schema.Union([ThreadNotMaterialized, AppendConflict, FenceRejected]);\n\n/**\n * The fail-fast refusal for any foreign operation OUTSIDE the closed route-capable subset\n * (plan §1.3): honesty over accidental distribution.\n */\nconst crossThreadLedgerError = (operation: string, target: string): LedgerError =>\n LedgerError.make({\n operation,\n message:\n `${operation} addressed to foreign Thread ${target} is not route-capable; the ` +\n \"closed cross-Object subset is admit, markReady, lookup, resolveAdmission, \" +\n \"requestAbort, and recordChildSettled. Every other ledger operation is lane-local by \" +\n \"construction and must execute inside the owning Thread's Durable Object.\",\n });\n\nconst crossThreadStoreError = (operation: string, target: string): ThreadStoreError =>\n ThreadStoreError.make({\n operation,\n message:\n `${operation} addressed to foreign Thread ${target} is not route-capable; the ` +\n \"closed cross-Object subset is materialize, append, read (paged), inspectTail, and \" +\n \"export. Observation and checkpoints are lane-local by construction and must execute \" +\n \"inside the owning Thread's Durable Object.\",\n });\n\nconst makeTransportCall = (transport: ThreadPortTransport[\"Service\"]) =>\n Effect.fn(\"DoPortRouting.transportCall\")(function* (target: ThreadId, call: PortRequest) {\n const encoded = yield* encodePortRequest(call).pipe(\n Effect.mapError((error) =>\n PortProtocolError.make({\n message: boundPortDiagnostic(`The port request could not be encoded: ${error.message}`),\n }),\n ),\n );\n\n const raw = yield* transport.call(target, encoded);\n\n return yield* decodePortResponse(raw).pipe(\n Effect.mapError((error) =>\n PortProtocolError.make({\n message: boundPortDiagnostic(`The port response could not be decoded: ${error.message}`),\n }),\n ),\n );\n });\n\ntype TransportCall = ReturnType<typeof makeTransportCall>;\n\nconst makeRoutedLedgerServices = Effect.fn(\"DoPortRouting.makeRoutedLedgerServices\")(function* (\n options: RoutedPortOptions,\n) {\n const local = yield* SubmissionLedger;\n const transport = yield* ThreadPortTransport;\n const transportCall: TransportCall = makeTransportCall(transport);\n const submissionTarget = routableSubmissionTarget(options.ownsThread);\n\n const routeFailure =\n (operation: string, target: string) =>\n (error: PortTransportError | PortProtocolError): LedgerError =>\n LedgerError.make({\n operation,\n message: boundPortDiagnostic(\n `Routed ${operation} to the Thread Object owning ${target} failed: ${error.message}`,\n ),\n cause: error,\n });\n\n /**\n * One routed ledger call: encode, deliver, decode, then narrow the uniform envelope to the\n * operation's own result and failure surface. A foreign `LedgerError` is always in-channel;\n * any failure outside the operation's declared surface — including protocol anomalies — is\n * folded into a `LedgerError` naming the anomaly instead of being erased or re-thrown raw.\n */\n const foreignLedgerCall = <ResultSchema extends Schema.Top, FailureSchema extends Schema.Top>(\n operation: string,\n target: ThreadId,\n call: PortRequest,\n resultSchema: ResultSchema,\n failureSchema: FailureSchema,\n ): Effect.Effect<ResultSchema[\"Type\"], FailureSchema[\"Type\"] | LedgerError> => {\n const isExpectedResult = Schema.is(resultSchema);\n const isExpectedFailure = Schema.is(failureSchema);\n\n return transportCall(target, call).pipe(\n Effect.mapError(routeFailure(operation, target)),\n Effect.flatMap(\n (response): Effect.Effect<ResultSchema[\"Type\"], FailureSchema[\"Type\"] | LedgerError> => {\n if (response._tag === \"PortFailed\") {\n const failure = response.failure;\n\n if (isExpectedFailure(failure)) return Effect.fail(failure);\n if (failure._tag === \"LedgerError\") return Effect.fail(failure);\n\n return Effect.fail(\n LedgerError.make({\n operation,\n message: boundPortDiagnostic(\n `The Thread Object owning ${target} answered ${operation} with the ` +\n `out-of-contract failure ${failure._tag}: ${failure.message}`,\n ),\n cause: failure,\n }),\n );\n }\n const result = response.result;\n\n if (!isExpectedResult(result)) {\n return Effect.fail(\n LedgerError.make({\n operation,\n message:\n `The Thread Object owning ${target} answered ${operation} with the ` +\n `mismatched result ${result._tag}.`,\n }),\n );\n }\n\n return Effect.succeed(result);\n },\n ),\n Effect.withSpan(\"DoPortRouting.foreignLedgerCall\", {\n attributes: { operation, target },\n }),\n );\n };\n\n /**\n * Routed `resolveAdmission` — where the S2 tri-state becomes real (plan §1.3): when the\n * owning Object cannot be reached, or its answer cannot be understood, the routed adapter\n * answers `AdmissionIndeterminate{reason}` and NEVER `NotAdmitted` — an unreachable\n * authority proves nothing, and only `NotAdmitted` permits an admission attempt (SUB-031).\n * A typed `LedgerError` answered BY the authority still fails typed: the authority was\n * reached and reported its own storage failure.\n */\n const resolveForeignAdmission = (\n target: ThreadId,\n request: SubmissionLookupByKey,\n ): Effect.Effect<\n | AdmissionIndeterminate\n | Extract<PortResult, { readonly _tag: \"LedgerResolveAdmissionResult\" }>[\"resolution\"],\n LedgerError\n > =>\n transportCall(target, LedgerResolveAdmissionCall.make({ request })).pipe(\n Effect.flatMap((response) => {\n if (response._tag === \"PortFailed\") {\n if (response.failure._tag === \"LedgerError\") return Effect.fail(response.failure);\n\n return Effect.succeed(\n AdmissionIndeterminate.make({\n reason: boundPortDiagnostic(\n `The Thread Object owning ${target} answered resolveAdmission with the ` +\n `out-of-contract failure ${response.failure._tag}: ${response.failure.message}`,\n ),\n }),\n );\n }\n if (response.result._tag !== \"LedgerResolveAdmissionResult\") {\n return Effect.succeed(\n AdmissionIndeterminate.make({\n reason: boundPortDiagnostic(\n `The Thread Object owning ${target} answered resolveAdmission with the ` +\n `mismatched result ${response.result._tag}.`,\n ),\n }),\n );\n }\n\n return Effect.succeed(response.result.resolution);\n }),\n Effect.catchTags({\n PortTransportError: (error) =>\n Effect.succeed(\n AdmissionIndeterminate.make({\n reason: boundPortDiagnostic(\n `The Thread Object owning ${target} is unreachable: ${error.message}`,\n ),\n }),\n ),\n PortProtocolError: (error) =>\n Effect.succeed(\n AdmissionIndeterminate.make({\n reason: boundPortDiagnostic(\n `The answer of the Thread Object owning ${target} could not be ` +\n `understood: ${error.message}`,\n ),\n }),\n ),\n }),\n Effect.withSpan(\"DoPortRouting.resolveForeignAdmission\", { attributes: { target } }),\n );\n\n const foreignLookupById = (\n operation: string,\n target: ThreadId,\n submissionId: SubmissionId,\n ): Effect.Effect<Option.Option<SubmissionSnapshot>, LedgerError> =>\n foreignLedgerCall(\n operation,\n target,\n LedgerLookupCall.make({ request: SubmissionLookupById.make({ submissionId }) }),\n LedgerLookupResult,\n NoAdditionalPortFailure,\n ).pipe(\n Effect.map((result) =>\n result.submission === undefined ? Option.none() : Option.some(result.submission),\n ),\n );\n\n /**\n * Enrich a LOCAL parent's recovery snapshot with the lane state of attached children whose\n * rows live in other Durable Objects (plan §1.3): markers first (the local facet already\n * consulted them), then a routed per-child `lookup` for any attached child that is neither\n * local nor marker-settled. A transport failure surfaces as `LedgerError` so the alarm\n * pass retries; the child's canonical Settlement remains the only authority (DUR-015).\n */\n const enrichChildAttachments = Effect.fn(\"DoPortRouting.enrichChildAttachments\")(function* (\n snapshot: RecoverySnapshot,\n ): Effect.fn.Return<RecoverySnapshot, LedgerError> {\n const operation = \"ledger load recovery snapshot\";\n\n const attachments = new Map(\n snapshot.childAttachments.map((attachment) => [attachment.childSubmissionId, attachment]),\n );\n\n let enriched = false;\n\n for (const reservation of snapshot.childReservations) {\n const childSubmissionId = reservation.childSubmissionId;\n\n if (childSubmissionId === undefined || attachments.has(childSubmissionId)) continue;\n const target = yield* submissionTarget(operation, childSubmissionId);\n\n // A local or opaque child identity was already answered authoritatively by the local\n // facet; absence there means the child admission never committed.\n if (target._tag !== \"foreign\") continue;\n const child = yield* foreignLookupById(operation, target.threadId, childSubmissionId);\n\n if (Option.isNone(child)) continue;\n attachments.set(\n childSubmissionId,\n ChildAttachmentSnapshot.make({\n toolCallId: reservation.parentToolCallId,\n childSubmissionId,\n childState: child.value.state,\n ...(child.value.settledOutcome === undefined\n ? {}\n : { childOutcome: child.value.settledOutcome }),\n }),\n );\n enriched = true;\n }\n if (!enriched) return snapshot;\n // Rebuild in reservation (parent Tool Call) order, the order the local facet documents.\n const ordered: Array<ChildAttachmentSnapshot> = [];\n\n for (const reservation of snapshot.childReservations) {\n if (reservation.childSubmissionId === undefined) continue;\n const attachment = attachments.get(reservation.childSubmissionId);\n\n if (attachment !== undefined) ordered.push(attachment);\n }\n\n return RecoverySnapshot.make({ ...snapshot, childAttachments: ordered });\n });\n\n const routed = SubmissionLedger.of({\n capabilities: local.capabilities,\n\n admit: (request) =>\n options.ownsThread(request.threadId)\n ? local.admit(request)\n : foreignLedgerCall(\n \"ledger admit\",\n request.threadId,\n LedgerAdmitCall.make({ request }),\n LedgerAdmitResult,\n Schema.Union([AdmissionConflict, AdmissionPolicyError]),\n ).pipe(Effect.map((reply) => reply.result)),\n\n markReady: (request) =>\n submissionTarget(\"ledger mark ready\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.markReady(request)\n : foreignLedgerCall(\n \"ledger mark ready\",\n target.threadId,\n LedgerMarkReadyCall.make({ request }),\n LedgerMarkReadyResult,\n NoAdditionalPortFailure,\n ).pipe(Effect.asVoid),\n ),\n ),\n\n lookup: (request) =>\n request._tag === \"SubmissionLookupById\"\n ? submissionTarget(\"ledger lookup\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.lookup(request)\n : foreignLookupById(\"ledger lookup\", target.threadId, request.submissionId),\n ),\n )\n : options.ownsThread(request.threadId)\n ? local.lookup(request)\n : foreignLedgerCall(\n \"ledger lookup\",\n request.threadId,\n LedgerLookupCall.make({ request }),\n LedgerLookupResult,\n NoAdditionalPortFailure,\n ).pipe(\n Effect.map((result) =>\n result.submission === undefined ? Option.none() : Option.some(result.submission),\n ),\n ),\n\n resolveAdmission: (request) =>\n options.ownsThread(request.threadId)\n ? local.resolveAdmission(request)\n : resolveForeignAdmission(request.threadId, request),\n\n requestAbort: (request) =>\n submissionTarget(\"ledger request abort\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.requestAbort(request)\n : foreignLedgerCall(\n \"ledger request abort\",\n target.threadId,\n LedgerRequestAbortCall.make({ request }),\n LedgerRequestAbortResult,\n AbortPortFailure,\n ).pipe(Effect.map((reply) => reply.intent)),\n ),\n ),\n\n recordChildSettled: (request) =>\n submissionTarget(\"ledger record child settled\", request.parentSubmissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.recordChildSettled(request)\n : foreignLedgerCall(\n \"ledger record child settled\",\n target.threadId,\n LedgerRecordChildSettledCall.make({ request }),\n LedgerRecordChildSettledResult,\n NoAdditionalPortFailure,\n ).pipe(Effect.map((reply) => reply.outcome)),\n ),\n ),\n\n // Every operation below is lane-local by construction (plan §1.3): a foreign address is\n // an out-of-contract call and fails fast typed instead of being quietly distributed.\n claim: (request) =>\n options.ownsThread(request.threadId)\n ? local.claim(request)\n : Effect.fail(crossThreadLedgerError(\"ledger claim\", request.threadId)),\n\n claimJoining: (request) =>\n options.ownsThread(request.threadId)\n ? local.claimJoining(request)\n : Effect.fail(crossThreadLedgerError(\"ledger claim joining\", request.threadId)),\n\n renewOwnership: (request) =>\n submissionTarget(\"ledger renew ownership\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.renewOwnership(request)\n : Effect.fail(crossThreadLedgerError(\"ledger renew ownership\", target.threadId)),\n ),\n ),\n\n releaseOwnership: (request) =>\n submissionTarget(\"ledger release ownership\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.releaseOwnership(request)\n : Effect.fail(crossThreadLedgerError(\"ledger release ownership\", target.threadId)),\n ),\n ),\n\n markInputApplied: (request) =>\n submissionTarget(\"ledger mark input applied\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.markInputApplied(request)\n : Effect.fail(crossThreadLedgerError(\"ledger mark input applied\", target.threadId)),\n ),\n ),\n\n reserveSettlement: (request) =>\n submissionTarget(\"ledger reserve settlement\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.reserveSettlement(request)\n : Effect.fail(crossThreadLedgerError(\"ledger reserve settlement\", target.threadId)),\n ),\n ),\n\n finalizeSettlement: (request) =>\n submissionTarget(\"ledger finalize settlement\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.finalizeSettlement(request)\n : Effect.fail(crossThreadLedgerError(\"ledger finalize settlement\", target.threadId)),\n ),\n ),\n\n markJoined: (request) =>\n submissionTarget(\"ledger mark joined\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.markJoined(request)\n : Effect.fail(crossThreadLedgerError(\"ledger mark joined\", target.threadId)),\n ),\n ),\n\n revertJoining: (request) =>\n submissionTarget(\"ledger revert joining\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.revertJoining(request)\n : Effect.fail(crossThreadLedgerError(\"ledger revert joining\", target.threadId)),\n ),\n ),\n\n suspend: (request) =>\n submissionTarget(\"ledger suspend\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.suspend(request)\n : Effect.fail(crossThreadLedgerError(\"ledger suspend\", target.threadId)),\n ),\n ),\n\n recordApprovalDecision: (command) =>\n submissionTarget(\"ledger record approval decision\", command.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.recordApprovalDecision(command)\n : Effect.fail(\n crossThreadLedgerError(\"ledger record approval decision\", target.threadId),\n ),\n ),\n ),\n\n markUnknown: (request) =>\n submissionTarget(\"ledger mark unknown\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.markUnknown(request)\n : Effect.fail(crossThreadLedgerError(\"ledger mark unknown\", target.threadId)),\n ),\n ),\n\n recordUnknownResolution: (command) =>\n submissionTarget(\"ledger record unknown resolution\", command.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.recordUnknownResolution(command)\n : Effect.fail(\n crossThreadLedgerError(\"ledger record unknown resolution\", target.threadId),\n ),\n ),\n ),\n\n reserveChildBudget: (request) =>\n submissionTarget(\"ledger reserve child budget\", request.parentSubmissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.reserveChildBudget(request)\n : Effect.fail(crossThreadLedgerError(\"ledger reserve child budget\", target.threadId)),\n ),\n ),\n\n // Reservation identities carry no Thread address; the reservation row lives in the\n // parent's own Object and these transitions are parent-lane-local by construction, so\n // they always execute on the local facet (which fails typed for an unknown row).\n attachChildToReservation: local.attachChildToReservation,\n beginChildBudgetRelease: local.beginChildBudgetRelease,\n releaseChildBudget: local.releaseChildBudget,\n\n // The local scan IS the whole worklist: one Thread per Object (durability §5).\n scanNonterminal: local.scanNonterminal,\n\n readAbortIntent: (request) =>\n submissionTarget(\"ledger read abort intent\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.readAbortIntent(request)\n : Effect.fail(crossThreadLedgerError(\"ledger read abort intent\", target.threadId)),\n ),\n ),\n\n loadRecoverySnapshot: (request) =>\n submissionTarget(\"ledger load recovery snapshot\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.loadRecoverySnapshot(request).pipe(Effect.flatMap(enrichChildAttachments))\n : Effect.fail(crossThreadLedgerError(\"ledger load recovery snapshot\", target.threadId)),\n ),\n ),\n });\n\n return Context.make(SubmissionLedger, routed);\n});\n\nconst makeRoutedStoreServices = Effect.fn(\"DoPortRouting.makeRoutedStoreServices\")(function* (\n options: RoutedPortOptions,\n) {\n const local = yield* ThreadStore;\n const checkpoints = local.checkpoints;\n const recoveryCheckpoints = local.recoveryCheckpoints;\n const transport = yield* ThreadPortTransport;\n const transportCall: TransportCall = makeTransportCall(transport);\n\n const routeFailure =\n (operation: string, target: string) =>\n (error: PortTransportError | PortProtocolError): ThreadStoreError =>\n ThreadStoreError.make({\n operation,\n message: boundPortDiagnostic(\n `Routed ${operation} to the Thread Object owning ${target} failed: ${error.message}`,\n ),\n cause: error,\n });\n\n /** The store twin of `foreignLedgerCall` with `ThreadStoreError` as the base error. */\n const foreignStoreCall = <ResultSchema extends Schema.Top, FailureSchema extends Schema.Top>(\n operation: string,\n target: ThreadId,\n call: PortRequest,\n resultSchema: ResultSchema,\n failureSchema: FailureSchema,\n ): Effect.Effect<ResultSchema[\"Type\"], FailureSchema[\"Type\"] | ThreadStoreError> => {\n const isExpectedResult = Schema.is(resultSchema);\n const isExpectedFailure = Schema.is(failureSchema);\n\n return transportCall(target, call).pipe(\n Effect.mapError(routeFailure(operation, target)),\n Effect.flatMap(\n (\n response,\n ): Effect.Effect<ResultSchema[\"Type\"], FailureSchema[\"Type\"] | ThreadStoreError> => {\n if (response._tag === \"PortFailed\") {\n const failure = response.failure;\n\n if (isExpectedFailure(failure)) return Effect.fail(failure);\n if (failure._tag === \"ThreadStoreError\") return Effect.fail(failure);\n\n return Effect.fail(\n ThreadStoreError.make({\n operation,\n message: boundPortDiagnostic(\n `The Thread Object owning ${target} answered ${operation} with the ` +\n `out-of-contract failure ${failure._tag}: ${failure.message}`,\n ),\n cause: failure,\n }),\n );\n }\n const result = response.result;\n\n if (!isExpectedResult(result)) {\n return Effect.fail(\n ThreadStoreError.make({\n operation,\n message:\n `The Thread Object owning ${target} answered ${operation} with the ` +\n `mismatched result ${result._tag}.`,\n }),\n );\n }\n\n return Effect.succeed(result);\n },\n ),\n Effect.withSpan(\"DoPortRouting.foreignStoreCall\", {\n attributes: { operation, target },\n }),\n );\n };\n\n const routed = ThreadStore.of({\n materialize: (request) =>\n options.ownsThread(request.threadId)\n ? local.materialize(request)\n : foreignStoreCall(\n \"thread materialize\",\n request.threadId,\n StoreMaterializeCall.make({ request }),\n StoreMaterializeResult,\n FenceRejected,\n ).pipe(Effect.asVoid),\n\n append: (request) =>\n options.ownsThread(request.threadId)\n ? local.append(request)\n : foreignStoreCall(\n \"thread append\",\n request.threadId,\n StoreAppendCall.make({ request }),\n StoreAppendResult,\n AppendPortFailure,\n ).pipe(Effect.map((reply) => reply.result)),\n\n read: (request) =>\n options.ownsThread(request.threadId)\n ? local.read(request)\n : Stream.unwrap(\n foreignStoreCall(\n \"thread read\",\n request.threadId,\n StoreReadPageCall.make({ request }),\n StoreReadPageResult,\n ThreadNotMaterialized,\n ).pipe(Effect.map((reply) => Stream.fromIterable(reply.records))),\n ),\n\n inspectTail: (request) =>\n options.ownsThread(request.threadId)\n ? local.inspectTail(request)\n : foreignStoreCall(\n \"thread inspect tail\",\n request.threadId,\n StoreInspectTailCall.make({ request }),\n StoreInspectTailResult,\n ThreadNotMaterialized,\n ).pipe(Effect.map((reply) => reply.tail)),\n\n export: (request) =>\n options.ownsThread(request.threadId)\n ? local.export(request)\n : foreignStoreCall(\n \"thread export\",\n request.threadId,\n StoreExportCall.make({ request }),\n StoreExportResult,\n ThreadNotMaterialized,\n ).pipe(Effect.map((reply) => reply.export)),\n\n // Observation and checkpoints are lane-local: the closed route-capable store subset\n // is materialize/append/read/inspectTail/export. Recovery cache misses can fall back\n // to those canonical reads, including when the cache belongs to a foreign Object.\n observe: (request) =>\n options.ownsThread(request.threadId)\n ? local.observe(request)\n : Stream.unwrap(Effect.fail(crossThreadStoreError(\"thread observe\", request.threadId))),\n\n ...(recoveryCheckpoints === undefined\n ? {}\n : {\n recoveryCheckpoints: {\n save: (request) =>\n options.ownsThread(request.checkpoint.threadId)\n ? recoveryCheckpoints.save(request)\n : Effect.fail(\n crossThreadStoreError(\n \"thread save recovery checkpoint\",\n request.checkpoint.threadId,\n ),\n ),\n load: (request) =>\n options.ownsThread(request.threadId)\n ? recoveryCheckpoints.load(request)\n : Effect.succeed(Option.none()),\n },\n }),\n ...(checkpoints === undefined\n ? {}\n : {\n checkpoints: {\n save: (request) =>\n options.ownsThread(request.checkpoint.threadId)\n ? checkpoints.save(request)\n : Effect.fail(\n crossThreadStoreError(\"thread save checkpoint\", request.checkpoint.threadId),\n ),\n load: (request) =>\n options.ownsThread(request.threadId)\n ? checkpoints.load(request)\n : Effect.fail(crossThreadStoreError(\"thread load checkpoint\", request.threadId)),\n },\n }),\n });\n\n return Context.make(ThreadStore, routed);\n});\n\n/**\n * Routing decorator over the LOCAL `SubmissionLedger` facet (plan §1.3): a request addressing\n * this Object's Thread executes locally; a route-capable request addressing another\n * Thread is Schema-encoded onto the `ThreadPortTransport` and executed by the\n * owning Object's local facet; any other foreign request fails fast typed. Provide the WP1\n * local facet (`submissionLedgerLayer`/`ledgerLayer`) and a transport to close it.\n */\nexport const routedSubmissionLedgerLayer = (\n options: RoutedPortOptions,\n): Layer.Layer<SubmissionLedger, never, SubmissionLedger | ThreadPortTransport> =>\n Layer.effectContext(makeRoutedLedgerServices(options));\n\n/**\n * Routing decorator over the LOCAL `ThreadStore` facet (plan §1.3): this-thread\n * requests execute locally; foreign materialize/append/read/inspectTail/export travel the\n * transport. Foreign recovery-cache loads return none for canonical replay; other foreign\n * checkpoint operations and observation fail fast typed.\n */\nexport const routedThreadStoreLayer = (\n options: RoutedPortOptions,\n): Layer.Layer<ThreadStore, never, ThreadStore | ThreadPortTransport> =>\n Layer.effectContext(makeRoutedStoreServices(options));\n\n// ---------------------------------------------------------------------------\n// Owner-side execution\n// ---------------------------------------------------------------------------\n\n/** Fold one port operation's typed failures into the uniform response envelope. */\nconst capture = <Failure extends PortFailure>(\n effect: Effect.Effect<PortResult, Failure>,\n): Effect.Effect<PortResponse> =>\n effect.pipe(\n Effect.map((result): PortResponse => PortSucceeded.make({ result })),\n Effect.catch((failure) => Effect.succeed<PortResponse>(PortFailed.make({ failure }))),\n );\n\n/**\n * Execute one decoded port request against THIS Object's LOCAL facets — the owner-side half\n * of the routed ports (plan §1.3). Callers must provide the WP1 local facets, never the\n * routed decorators: the routing layer already established that this Object owns the\n * addressed Thread, and re-routing here could bounce a request between Objects.\n * Failures never escape — every typed port failure becomes a `PortFailed` envelope that\n * re-decodes on the caller side.\n */\nexport const executePortRequest = Effect.fn(\"DoPortRouting.executePortRequest\")(function* (\n request: PortRequest,\n): Effect.fn.Return<PortResponse, never, SubmissionLedger | ThreadStore> {\n switch (request._tag) {\n case \"LedgerAdmit\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .admit(request.request)\n .pipe(Effect.map((result) => LedgerAdmitResult.make({ result }))),\n );\n }\n case \"LedgerMarkReady\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger.markReady(request.request).pipe(Effect.map(() => LedgerMarkReadyResult.make({}))),\n );\n }\n case \"LedgerLookup\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .lookup(request.request)\n .pipe(\n Effect.map((submission) =>\n Option.isSome(submission)\n ? LedgerLookupResult.make({ submission: submission.value })\n : LedgerLookupResult.make({}),\n ),\n ),\n );\n }\n case \"LedgerResolveAdmission\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .resolveAdmission(request.request)\n .pipe(Effect.map((resolution) => LedgerResolveAdmissionResult.make({ resolution }))),\n );\n }\n case \"LedgerRequestAbort\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .requestAbort(request.request)\n .pipe(Effect.map((intent) => LedgerRequestAbortResult.make({ intent }))),\n );\n }\n case \"LedgerRecordChildSettled\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .recordChildSettled(request.request)\n .pipe(Effect.map((outcome) => LedgerRecordChildSettledResult.make({ outcome }))),\n );\n }\n case \"StoreMaterialize\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store.materialize(request.request).pipe(Effect.map(() => StoreMaterializeResult.make({}))),\n );\n }\n case \"StoreAppend\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store\n .append(request.request)\n .pipe(Effect.map((result) => StoreAppendResult.make({ result }))),\n );\n }\n case \"StoreReadPage\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store.read(request.request).pipe(\n Stream.runCollect,\n Effect.map((records) => StoreReadPageResult.make({ records: [...records] })),\n ),\n );\n }\n case \"StoreInspectTail\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store\n .inspectTail(request.request)\n .pipe(Effect.map((tail) => StoreInspectTailResult.make({ tail }))),\n );\n }\n case \"StoreExport\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store\n .export(request.request)\n .pipe(Effect.map((threadExport) => StoreExportResult.make({ export: threadExport }))),\n );\n }\n }\n});\n\n/**\n * The last-resort wire fallback when even encoding a response fails: the literal encoded\n * form of `PortFailed(PortProtocolError)` — tagged classes of bounded strings encode to\n * exactly this shape, so no Schema round trip is needed to produce it.\n */\nconst encodedProtocolFailure = (message: string): unknown => ({\n _tag: \"PortFailed\",\n failure: { _tag: \"PortProtocolError\", message: boundPortDiagnostic(message) },\n});\n\n/**\n * The complete owner-side endpoint body for `portCall` (D-P6-3): decode the wire request,\n * execute it against this Object's LOCAL facets, and answer with the encoded response\n * envelope. Total by construction — a request that cannot be decoded, or a response that\n * cannot be encoded, answers `PortFailed(PortProtocolError)` instead of throwing, so the\n * transport never has to interpret exceptions as protocol answers.\n */\nexport const handleEncodedPortRequest = Effect.fn(\"DoPortRouting.handleEncodedPortRequest\")(\n function* (encoded: unknown): Effect.fn.Return<unknown, never, SubmissionLedger | ThreadStore> {\n const response = yield* decodePortRequest(encoded).pipe(\n Effect.flatMap(executePortRequest),\n Effect.catch((error) =>\n Effect.succeed<PortResponse>(\n PortFailed.make({\n failure: PortProtocolError.make({\n message: boundPortDiagnostic(\n `The port request could not be decoded: ${error.message}`,\n ),\n }),\n }),\n ),\n ),\n );\n\n return yield* encodePortResponse(response).pipe(\n Effect.catch((error) =>\n Effect.succeed(\n encodedProtocolFailure(`The port response could not be encoded: ${error.message}`),\n ),\n ),\n );\n },\n);\n"],"mappings":"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"}
@@ -325,7 +325,10 @@ const ensureCurrentStorage = Effect.fn("DoJournal.ensureCurrentStorage")(functio
325
325
  supportedVersion: 6,
326
326
  message: "The Durable Object contains unversioned Effect Agent tables. Refusing to mutate ambiguous stored data; retain it for inspection with its original writer."
327
327
  });
328
- yield* SqliteMigrator.run({ loader: doMigrations }).pipe(Effect.provideService(SqlClient.SqlClient, sql), Effect.mapError((error) => DoStorageError.make({
328
+ yield* SqliteMigrator.run({
329
+ loader: doMigrations,
330
+ table: "effect_sql_migrations_agent_threads"
331
+ }).pipe(Effect.provideService(SqlClient.SqlClient, sql), Effect.mapError((error) => DoStorageError.make({
329
332
  cause: error,
330
333
  operation: "initialize current storage",
331
334
  message: error.message
@@ -985,4 +988,4 @@ const initializeDoJournal = ensureCurrentStorage;
985
988
  //#endregion
986
989
  export { initializeDoJournal as a, decodeRows as i, RawCheckpoint as n, RawReadRequest as r, RawAppendRequest as t };
987
990
 
988
- //# sourceMappingURL=do-journal-DnzUmhPA.mjs.map
991
+ //# sourceMappingURL=do-journal-DHqCQeBU.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"do-journal-DHqCQeBU.mjs","names":[],"sources":["../src/internal/do-journal.ts"],"sourcesContent":["import { EMPTY_TAIL_DIGEST } from \"@effect-agent/thread/Digest\";\nimport { CanonicalSequence, ProducerEpoch } from \"@effect-agent/thread/Records\";\nimport { checkV2ThreadLayout } from \"@effect-agent/thread/SqlStorageV2Upgrade\";\nimport {\n MAX_THREAD_EXPORT_RECORDS,\n CheckpointRejected,\n FenceRejected,\n ThreadNotMaterialized,\n type SaveRecoveryCheckpointRequest,\n} from \"@effect-agent/thread/ThreadStore\";\nimport { SqliteMigrator } from \"@effect/sql-sqlite-do\";\nimport { Effect, Schema, Stream } from \"effect\";\nimport * as SqlClient from \"effect/unstable/sql/SqlClient\";\nimport { SqlError } from \"effect/unstable/sql/SqlError\";\n\nimport {\n type DoStorageFailpointError,\n DoAppendConflict,\n DoCheckpointConflict,\n DoFenceRejected,\n DoStorageCompatibilityError,\n DoStorageCorruptionError,\n DoStorageError,\n DoValueBoundExceeded,\n type DoStorageFailpointLocation,\n} from \"../DoStorageError.ts\";\nimport { createMessageDeliveryTables } from \"./message-delivery-schema.ts\";\nimport { CurrentDoStorageVersion, createNonterminalIndex, doMigrations } from \"./migrations.ts\";\nimport { createRecoveryCheckpointTable } from \"./recovery-checkpoint-schema.ts\";\n\n/**\n * Static schema ceiling for stored text columns. Writes are bounded in BYTES by the\n * configured `maxStoredValueBytes` (always ≤ 2,000,000); UTF-8 byte length is never smaller\n * than UTF-16 string length, so any value that passed the byte bound also passes this\n * decode-side character ceiling.\n */\nconst BoundedStoredText = Schema.String.check(Schema.isMaxLength(2_000_000));\nconst BoundedIdentifier = Schema.NonEmptyString.check(Schema.isMaxLength(1024));\nconst MAX_RECORDS_PER_THREAD = MAX_THREAD_EXPORT_RECORDS;\nconst ZERO_SEQUENCE = Schema.decodeSync(CanonicalSequence)(0);\nconst MAX_IDENTIFIER_LENGTH = 1_024;\nconst MAX_READ_PAGE_JSON_BYTES = 4 * 1024 * 1024;\n/** Durable Object SQL storage allows at most 100 bound parameters per statement. */\nconst MAX_BOUND_PARAMETERS = 100;\nconst isSqlError = Schema.is(SqlError);\n\nconst storedTextBytes = (value: string): number => new TextEncoder().encode(value).byteLength;\n\nconst chunked = <A>(values: ReadonlyArray<A>, size: number): Array<ReadonlyArray<A>> => {\n const chunks: Array<ReadonlyArray<A>> = [];\n\n for (let index = 0; index < values.length; index += size) {\n chunks.push(values.slice(index, index + size));\n }\n\n return chunks;\n};\n\nclass DoMetaRow extends Schema.Class<DoMetaRow>(\"DoMetaRow\")({\n value: Schema.NonEmptyString.check(Schema.isMaxLength(128)),\n}) {}\n\nclass DoNameRow extends Schema.Class<DoNameRow>(\"DoNameRow\")({\n name: BoundedIdentifier,\n}) {}\n\nclass ThreadRow extends Schema.Class<ThreadRow>(\"ThreadRow\")({\n thread_id: BoundedIdentifier,\n created_at: Schema.NonEmptyString.check(Schema.isMaxLength(128)),\n producer_epoch: ProducerEpoch,\n tail_digest: BoundedStoredText,\n tail_sequence: CanonicalSequence,\n}) {}\n\nclass BatchRow extends Schema.Class<BatchRow>(\"BatchRow\")({\n batch_digest: BoundedStoredText,\n batch_id: BoundedIdentifier,\n batch_json: BoundedStoredText,\n thread_id: BoundedIdentifier,\n first_sequence: CanonicalSequence,\n last_sequence: CanonicalSequence,\n tail_digest: BoundedStoredText,\n}) {}\n\nclass RecordRow extends Schema.Class<RecordRow>(\"RecordRow\")({\n batch_id: BoundedIdentifier,\n thread_id: BoundedIdentifier,\n record_id: BoundedIdentifier,\n record_json: BoundedStoredText,\n sequence: CanonicalSequence,\n}) {}\n\nconst ReadPlanRow = Schema.Struct({\n sequence: CanonicalSequence,\n record_json_bytes: Schema.Natural.check(Schema.isLessThanOrEqualTo(MAX_READ_PAGE_JSON_BYTES)),\n});\n\ntype ReadPage = [typeof ReadPlanRow.Type, ...Array<typeof ReadPlanRow.Type>];\n\nclass CheckpointRow extends Schema.Class<CheckpointRow>(\"CheckpointRow\")({\n checkpoint_json: BoundedStoredText,\n thread_id: BoundedIdentifier,\n tail_digest: BoundedStoredText,\n through_sequence: CanonicalSequence,\n}) {}\n\nexport class RawRecord extends Schema.Class<RawRecord>(\n \"@effect-agent/storage-cloudflare/RawRecord\",\n)({\n recordId: BoundedIdentifier,\n recordJson: BoundedStoredText,\n}) {}\n\nexport class RawAppendRequest extends Schema.Class<RawAppendRequest>(\n \"@effect-agent/storage-cloudflare/RawAppendRequest\",\n)({\n batchDigest: BoundedStoredText,\n batchId: BoundedIdentifier,\n batchJson: BoundedStoredText,\n threadId: BoundedIdentifier,\n expectedTailDigest: BoundedStoredText,\n expectedTailSequence: CanonicalSequence,\n producerEpoch: ProducerEpoch,\n records: Schema.NonEmptyArray(RawRecord).check(Schema.isMaxLength(256)),\n tailDigest: BoundedStoredText,\n}) {}\n\nexport class RawAppendResult extends Schema.Class<RawAppendResult>(\n \"@effect-agent/storage-cloudflare/RawAppendResult\",\n)({\n firstSequence: CanonicalSequence,\n lastSequence: CanonicalSequence,\n replayed: Schema.Boolean,\n tailDigest: BoundedStoredText,\n}) {}\n\nexport class RawReadRequest extends Schema.Class<RawReadRequest>(\n \"@effect-agent/storage-cloudflare/RawReadRequest\",\n)({\n threadId: BoundedIdentifier,\n fromSequenceExclusive: CanonicalSequence,\n limit: Schema.Int.check(Schema.isGreaterThan(0), Schema.isLessThanOrEqualTo(1_024)),\n}) {}\n\nexport class RawCheckpoint extends Schema.Class<RawCheckpoint>(\n \"@effect-agent/storage-cloudflare/RawCheckpoint\",\n)({\n checkpointJson: BoundedStoredText,\n threadId: BoundedIdentifier,\n tailDigest: BoundedStoredText,\n throughSequence: CanonicalSequence,\n}) {}\n\nexport class RawThreadExport extends Schema.Class<RawThreadExport>(\n \"@effect-agent/storage-cloudflare/RawThreadExport\",\n)({\n thread: ThreadRow,\n records: Schema.Array(RecordRow),\n}) {}\n\ntype AppendError =\n | DoAppendConflict\n | DoFenceRejected\n | DoStorageCorruptionError\n | DoStorageError\n | DoStorageFailpointError\n | DoValueBoundExceeded;\n\ntype CheckpointError =\n | DoCheckpointConflict\n | DoStorageCorruptionError\n | DoStorageError\n | DoValueBoundExceeded;\n\ntype DoJournalFailpoint = (\n location: DoStorageFailpointLocation,\n) => Effect.Effect<void, DoStorageFailpointError>;\n\nconst noFailpoint: DoJournalFailpoint = () => Effect.void;\n\nconst storageError =\n (operation: string) =>\n (error: SqlError): DoStorageError =>\n DoStorageError.make({\n cause: error,\n operation,\n message: error.message,\n });\n\n/** Decode raw Durable Object SQLite rows against a Schema, reporting failures as typed corruption. */\nexport const decodeRows = Effect.fn(\n <A, I>(\n schema: Schema.Codec<ReadonlyArray<A>, ReadonlyArray<I>>,\n table: string,\n rowKey: string,\n rows: unknown,\n ): Effect.Effect<ReadonlyArray<A>, DoStorageCorruptionError> =>\n Schema.decodeUnknownEffect(schema)(rows).pipe(\n Effect.mapError((error) =>\n DoStorageCorruptionError.make({\n table,\n rowKey,\n message: String(error),\n }),\n ),\n ),\n);\n\n/** Decode exactly one raw row against a Schema, reporting failures as typed corruption. */\nexport const decodeSingleRow = Effect.fn(\n <A, I>(\n schema: Schema.Codec<ReadonlyArray<A>, ReadonlyArray<I>>,\n table: string,\n rowKey: string,\n rows: unknown,\n ): Effect.Effect<A, DoStorageCorruptionError> =>\n decodeRows(schema, table, rowKey, rows).pipe(\n Effect.flatMap((decoded) =>\n decoded.length === 1\n ? Effect.succeed(decoded[0])\n : Effect.fail(\n DoStorageCorruptionError.make({\n table,\n rowKey,\n message: `Expected exactly one row but found ${decoded.length}.`,\n }),\n ),\n ),\n ),\n);\n\n/** Column inventory of the supported v3 predecessor, independent of physical column order. */\nconst predecessorColumns = {\n effect_agent_threads: [\n \"thread_id\",\n \"created_at\",\n \"tail_sequence\",\n \"tail_digest\",\n \"producer_epoch\",\n ],\n effect_agent_canonical_batches: [\n \"thread_id\",\n \"batch_id\",\n \"first_sequence\",\n \"last_sequence\",\n \"batch_digest\",\n \"tail_digest\",\n \"batch_json\",\n ],\n effect_agent_canonical_records: [\"thread_id\", \"sequence\", \"record_id\", \"batch_id\", \"record_json\"],\n effect_agent_checkpoints: [\"thread_id\", \"through_sequence\", \"tail_digest\", \"checkpoint_json\"],\n effect_agent_submissions: [\n \"submission_id\",\n \"thread_id\",\n \"queue_sequence\",\n \"principal\",\n \"idempotency_key\",\n \"agent_id\",\n \"agent_digests_json\",\n \"deployment_id\",\n \"input_json\",\n \"input_digest\",\n \"receipt_id\",\n \"state\",\n \"settled_outcome\",\n \"created_at\",\n \"ready_at\",\n \"input_applied_record_id\",\n \"input_applied_sequence\",\n \"joined_host_submission_id\",\n \"suspended_reason_json\",\n \"suspended_at\",\n \"unknown_reason\",\n \"unknown_tool_call_ids_json\",\n \"parent_submission_id\",\n \"parent_tool_call_id\",\n \"admission_group\",\n \"admission_fence_json\",\n ],\n effect_agent_submission_ownership: [\n \"submission_id\",\n \"attempt_id\",\n \"ownership_token\",\n \"producer_epoch\",\n \"owner_producer_id\",\n \"lease_expires_at\",\n ],\n effect_agent_attempts: [\n \"attempt_id\",\n \"submission_id\",\n \"thread_id\",\n \"owner_producer_id\",\n \"producer_epoch\",\n \"claimed_at\",\n ],\n effect_agent_settlement_reservations: [\n \"submission_id\",\n \"settlement_id\",\n \"outcome\",\n \"record_id\",\n \"record_json\",\n \"record_digest\",\n \"reserved_at\",\n \"finalized_at\",\n ],\n effect_agent_abort_intents: [\n \"submission_id\",\n \"author\",\n \"reason\",\n \"requested_at\",\n \"canonical_record_id\",\n ],\n effect_agent_approval_decisions: [\n \"submission_id\",\n \"tool_call_id\",\n \"decision\",\n \"resolver\",\n \"reason\",\n \"decided_at\",\n ],\n effect_agent_unknown_resolutions: [\n \"submission_id\",\n \"tool_call_id\",\n \"author\",\n \"reason\",\n \"resolution_json\",\n \"resolved_at\",\n ],\n effect_agent_child_reservations: [\n \"reservation_id\",\n \"parent_submission_id\",\n \"parent_tool_call_id\",\n \"child_submission_id\",\n \"status\",\n \"allocation_json\",\n \"allocation_digest\",\n \"accounting_json\",\n \"reserved_at\",\n \"release_began_at\",\n \"released_at\",\n ],\n effect_agent_meta: [\"key\", \"value\"],\n effect_agent_child_settlements: [\n \"parent_submission_id\",\n \"child_submission_id\",\n \"child_outcome\",\n \"recorded_at\",\n ],\n} as const;\n\nconst checkPredecessorLayout = Effect.fn(\"DoJournal.checkPredecessorLayout\")(function* (\n version: 3 | 4 | 5,\n) {\n const sql = yield* SqlClient.SqlClient;\n\n const messageColumns =\n version === 3\n ? predecessorColumns\n : {\n ...predecessorColumns,\n effect_agent_submissions: [\n ...predecessorColumns.effect_agent_submissions,\n \"worker_admission_json\",\n \"message_admission_json\",\n ],\n effect_agent_message_deliveries: [\n \"owner_thread_id\",\n \"message_id\",\n \"version\",\n \"state\",\n \"deadline_at_millis\",\n \"record_json\",\n ],\n };\n\n const expectedColumns = {\n ...messageColumns,\n ...(version === 5\n ? {\n effect_agent_recovery_checkpoints: [\n \"thread_id\",\n \"through_sequence\",\n \"tail_digest\",\n \"checkpoint_json\",\n ],\n }\n : {}),\n };\n\n for (const [table, expected] of Object.entries(expectedColumns)) {\n const columns = yield* decodeRows(\n Schema.Array(Schema.Struct({ name: BoundedIdentifier })),\n table,\n \"schema\",\n yield* sql.unsafe(`PRAGMA table_info(${table})`),\n );\n\n const names = new Set<string>(expected);\n\n if (columns.length !== names.size || columns.some((column) => !names.has(column.name)))\n return yield* DoStorageCompatibilityError.make({\n actualVersion: version,\n supportedVersion: CurrentDoStorageVersion,\n message: `The v${version} ${table} columns do not match the supported predecessor; no upgrade was committed.`,\n });\n }\n});\n\nconst REQUIRED_TABLES = [\n \"effect_agent_abort_intents\",\n \"effect_agent_approval_decisions\",\n \"effect_agent_attempts\",\n \"effect_agent_canonical_batches\",\n \"effect_agent_canonical_records\",\n \"effect_agent_checkpoints\",\n \"effect_agent_child_reservations\",\n \"effect_agent_child_settlements\",\n \"effect_agent_threads\",\n \"effect_agent_meta\",\n \"effect_agent_settlement_reservations\",\n \"effect_agent_submission_ownership\",\n \"effect_agent_submissions\",\n \"effect_agent_unknown_resolutions\",\n] as const;\n\n/**\n * Supported-predecessor or fresh storage gate (DEPLOY-008) over `effect_agent_meta` instead of\n * `PRAGMA user_version` (unverified on Durable Object SQL storage; a meta table is portable\n * regardless). No WAL check (Durable Object storage owns durability and confirms writes\n * through output gates) and no busy timeout (a Durable Object has exactly one writer): the\n * Node machinery those served has no DC analogue and is deliberately absent.\n */\nconst ensureCurrentStorage = Effect.fn(\"DoJournal.ensureCurrentStorage\")(function* (\n sql: SqlClient.SqlClient,\n failpoint: DoJournalFailpoint = noFailpoint,\n maxStoredValueBytes: number,\n) {\n const metaTableRows = yield* sql<Record<string, unknown>>`\n SELECT name\n FROM sqlite_master\n WHERE type = 'table'\n AND name = 'effect_agent_meta'\n `.pipe(Effect.mapError(storageError(\"read storage version table\")));\n\n const metaTables = yield* decodeRows(\n Schema.Array(DoNameRow),\n \"sqlite_master\",\n \"effect_agent_meta\",\n metaTableRows,\n );\n\n if (metaTables.length === 0) {\n const existingRows = yield* sql<Record<string, unknown>>`\n SELECT name\n FROM sqlite_master\n WHERE type = 'table'\n AND name LIKE 'effect_agent_%'\n ORDER BY name\n `.pipe(Effect.mapError(storageError(\"inspect unversioned storage\")));\n\n const existing = yield* decodeRows(\n Schema.Array(DoNameRow),\n \"sqlite_master\",\n \"effect_agent_%\",\n existingRows,\n );\n\n if (existing.length > 0) {\n return yield* DoStorageCompatibilityError.make({\n actualVersion: 0,\n supportedVersion: CurrentDoStorageVersion,\n message:\n \"The Durable Object contains unversioned Effect Agent tables. Refusing to mutate ambiguous stored data; retain it for inspection with its original writer.\",\n });\n }\n\n yield* SqliteMigrator.run({\n loader: doMigrations,\n // An application can share this SQL client and own its own migration history.\n // Keep bookkeeping outside effect_agent_% so interrupted unversioned schemas\n // still fail the ambiguity check above.\n table: \"effect_sql_migrations_agent_threads\",\n }).pipe(\n // SqliteMigrator depends on the generic client supplied by this adapter. The concrete\n // Durable Object client is kept at the outer Layer boundary.\n Effect.provideService(SqlClient.SqlClient, sql),\n Effect.mapError((error) =>\n DoStorageError.make({\n cause: error,\n operation: \"initialize current storage\",\n message: error.message,\n }),\n ),\n );\n } else {\n const versionRows = yield* sql<Record<string, unknown>>`\n SELECT value\n FROM effect_agent_meta\n WHERE key = 'storage_version'\n `.pipe(Effect.mapError(storageError(\"read storage version\")));\n\n const version = yield* decodeSingleRow(\n Schema.Array(DoMetaRow),\n \"effect_agent_meta\",\n \"storage_version\",\n versionRows,\n );\n\n if (\n version.value === \"2\" ||\n version.value === \"3\" ||\n version.value === \"4\" ||\n version.value === \"5\"\n ) {\n yield* sql\n .withTransaction(\n Effect.gen(function* () {\n const current = yield* sql<{\n value: string;\n }>`SELECT value FROM effect_agent_meta WHERE key='storage_version'`;\n\n if (current.length === 1 && current[0].value === String(CurrentDoStorageVersion))\n return;\n if (\n current.length !== 1 ||\n (current[0].value !== \"2\" &&\n current[0].value !== \"3\" &&\n current[0].value !== \"4\" &&\n current[0].value !== \"5\")\n )\n return yield* DoStorageCompatibilityError.make({\n actualVersion: -1,\n supportedVersion: CurrentDoStorageVersion,\n message: \"Storage version changed while acquiring the upgrade transaction.\",\n });\n\n const required = yield* decodeRows(\n Schema.Array(DoNameRow),\n \"sqlite_master\",\n \"required_tables\",\n yield* sql`SELECT name FROM sqlite_master WHERE type='table' AND name IN ${sql.in([...REQUIRED_TABLES])}`,\n );\n\n if (required.length !== REQUIRED_TABLES.length)\n return yield* DoStorageCompatibilityError.make({\n actualVersion: Number(current[0].value),\n supportedVersion: CurrentDoStorageVersion,\n message:\n \"The predecessor store is missing required tables. Retain the original store for inspection; no upgrade was committed.\",\n });\n\n const recoveryTables =\n yield* sql`SELECT name FROM sqlite_master WHERE type='table' AND name='effect_agent_recovery_checkpoints'`;\n\n if (recoveryTables.length !== (current[0].value === \"5\" ? 1 : 0))\n return yield* DoStorageCompatibilityError.make({\n actualVersion: Number(current[0].value),\n supportedVersion: CurrentDoStorageVersion,\n message:\n \"The predecessor recovery checkpoint storage does not match its version; refusing ambiguous data without mutation.\",\n });\n\n const indexes =\n yield* sql`SELECT name FROM sqlite_master WHERE name='effect_agent_submissions_nonterminal'`;\n\n if (indexes.length !== 0)\n return yield* DoStorageCompatibilityError.make({\n actualVersion: Number(current[0].value),\n supportedVersion: CurrentDoStorageVersion,\n message:\n \"The predecessor already contains the nonterminal index; refusing ambiguous storage without mutation.\",\n });\n if (current[0].value === \"2\") {\n yield* checkV2ThreadLayout();\n for (const statement of [\n sql`ALTER TABLE effect_agent_submissions ADD COLUMN admission_group TEXT`,\n sql`ALTER TABLE effect_agent_submissions ADD COLUMN admission_fence_json TEXT`,\n sql`CREATE INDEX effect_agent_submissions_group ON effect_agent_submissions (thread_id, admission_group, state)`,\n ]) {\n yield* failpoint(\"upgrade:before-mutation\");\n yield* statement;\n yield* failpoint(\"upgrade:after-mutation\");\n }\n }\n if (current[0].value === \"3\") yield* checkPredecessorLayout(3);\n if (current[0].value === \"4\") yield* checkPredecessorLayout(4);\n if (current[0].value === \"5\") yield* checkPredecessorLayout(5);\n if (current[0].value === \"2\" || current[0].value === \"3\") {\n yield* failpoint(\"upgrade:before-mutation\");\n yield* sql`ALTER TABLE effect_agent_submissions ADD COLUMN worker_admission_json TEXT`;\n yield* failpoint(\"upgrade:after-mutation\");\n yield* failpoint(\"upgrade:before-mutation\");\n yield* sql`ALTER TABLE effect_agent_submissions ADD COLUMN message_admission_json TEXT`;\n yield* failpoint(\"upgrade:after-mutation\");\n yield* failpoint(\"upgrade:before-mutation\");\n yield* createMessageDeliveryTables;\n yield* failpoint(\"upgrade:after-mutation\");\n }\n if (current[0].value !== \"5\") {\n yield* failpoint(\"upgrade:before-mutation\");\n yield* createRecoveryCheckpointTable;\n yield* failpoint(\"upgrade:after-mutation\");\n }\n yield* failpoint(\"upgrade:before-mutation\");\n yield* createNonterminalIndex;\n yield* failpoint(\"upgrade:after-mutation\");\n yield* failpoint(\"upgrade:before-version\");\n yield* sql`UPDATE effect_agent_meta SET value='6' WHERE key='storage_version'`;\n yield* failpoint(\"upgrade:after-version\");\n }),\n )\n .pipe(\n Effect.catchTag(\"DoStorageFailpointError\", (error) =>\n DoStorageError.make({\n cause: error,\n operation: \"upgrade storage\",\n message: error.message,\n }),\n ),\n Effect.catchTag(\"StorageUpgradeError\", (error) =>\n DoStorageCorruptionError.make({\n table: error.table,\n rowKey: error.rowKey,\n message: error.message,\n }),\n ),\n Effect.catchTag(\"SqlError\", storageError(\"upgrade supported thread storage\")),\n );\n } else if (version.value !== String(CurrentDoStorageVersion)) {\n const actualVersion = Number.parseInt(version.value, 10);\n\n return yield* DoStorageCompatibilityError.make({\n actualVersion: Number.isSafeInteger(actualVersion) ? actualVersion : -1,\n supportedVersion: CurrentDoStorageVersion,\n message:\n `The Durable Object uses unsupported storage version ${version.value}; ` +\n `this build supports exactly version ${CurrentDoStorageVersion}. ` +\n \"Only supported v2, v3, v4 and v5 can be upgraded automatically. Keep the original store and use a compatible library version.\",\n });\n }\n }\n\n const requiredRows = yield* sql<Record<string, unknown>>`\n SELECT name\n FROM sqlite_master\n WHERE (type = 'table'\n AND name IN ${sql.in([...REQUIRED_TABLES, \"effect_agent_message_deliveries\", \"effect_agent_recovery_checkpoints\"])}\n ) OR (type = 'index' AND name = 'effect_agent_submissions_nonterminal')\n ORDER BY name\n `.pipe(Effect.mapError(storageError(\"verify storage tables\")));\n\n const required = yield* decodeRows(\n Schema.Array(DoNameRow),\n \"sqlite_master\",\n \"required_tables\",\n requiredRows,\n );\n\n if (required.length !== REQUIRED_TABLES.length + 3) {\n return yield* DoStorageCompatibilityError.make({\n actualVersion: CurrentDoStorageVersion,\n supportedVersion: CurrentDoStorageVersion,\n message:\n \"The Durable Object claims the current format but is missing required tables or its nonterminal index. Retain the original store for inspection.\",\n });\n }\n\n return makeJournal(sql, failpoint, maxStoredValueBytes);\n});\n\nconst makeJournal = (\n sql: SqlClient.SqlClient,\n failpoint: DoJournalFailpoint,\n maxStoredValueBytes: number,\n) => {\n /** Typed pre-write refusal for any single value over the configured byte bound. */\n const checkValueBound = (\n operation: string,\n value: string,\n ): Effect.Effect<void, DoValueBoundExceeded> => {\n const actualBytes = storedTextBytes(value);\n\n return actualBytes > maxStoredValueBytes\n ? Effect.fail(\n DoValueBoundExceeded.make({\n actualBytes,\n maxBytes: maxStoredValueBytes,\n operation,\n }),\n )\n : Effect.void;\n };\n\n /**\n * Runs one journal write transaction on the Durable Object storage-backed\n * `withTransaction` (`ctx.storage.transaction()` under the hood). Within one Durable\n * Object there is exactly ONE writer, so the Node `BEGIN IMMEDIATE` + busy-retry +\n * `SqliteWriteContention` machinery has no analogue here and is deliberately absent.\n * Ownership-token and epoch checks still run INSIDE the transaction, so fencing atomicity\n * (DUR-006) is preserved identically.\n *\n * Journal write transactions are always top level: the Durable Object client rejects\n * nested transactions, so new journal operations must not wrap this helper inside another\n * transaction.\n */\n const withWriteTransaction =\n (operation: string) =>\n <A, E>(effect: Effect.Effect<A, E>): Effect.Effect<A, E | DoStorageError> =>\n sql.withTransaction(effect).pipe(\n Effect.mapError((error) => (isSqlError(error) ? storageError(operation)(error) : error)),\n Effect.withSpan(\"DoJournal.withWriteTransaction\", { attributes: { operation } }),\n );\n\n const materialize = Effect.fn(\"DoJournal.materialize\")(function* (\n threadId: string,\n createdAt: string,\n emptyTailDigest: string,\n producerEpoch: ProducerEpoch,\n ): Effect.fn.Return<\n void,\n DoFenceRejected | DoStorageCorruptionError | DoStorageError | DoValueBoundExceeded\n > {\n if (threadId.length > MAX_IDENTIFIER_LENGTH) {\n return yield* DoStorageError.make({\n operation: \"materialize thread\",\n message: \"Thread identity exceeds the Durable Object storage bounds.\",\n });\n }\n yield* checkValueBound(\"materialize thread\", emptyTailDigest);\n yield* withWriteTransaction(\"materialize transaction\")(\n Effect.gen(function* () {\n const existingRows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n created_at,\n tail_sequence,\n tail_digest,\n producer_epoch\n FROM effect_agent_threads\n WHERE thread_id = ${threadId}\n `.pipe(Effect.mapError(storageError(\"read materialized thread\")));\n\n const existing = yield* decodeRows(\n Schema.Array(ThreadRow),\n \"effect_agent_threads\",\n threadId,\n existingRows,\n );\n\n if (existing.length > 1) {\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_threads\",\n rowKey: threadId,\n message: \"A thread primary key returned more than one row.\",\n });\n }\n if (existing.length === 0) {\n yield* sql`\n INSERT INTO effect_agent_threads (\n thread_id,\n created_at,\n tail_sequence,\n tail_digest,\n producer_epoch\n ) VALUES (\n ${threadId},\n ${createdAt},\n 0,\n ${emptyTailDigest},\n ${producerEpoch}\n )\n `.pipe(Effect.mapError(storageError(\"materialize thread\")));\n\n return;\n }\n if (producerEpoch < existing[0].producer_epoch) {\n return yield* DoFenceRejected.make({\n producerEpoch,\n actualEpoch: existing[0].producer_epoch,\n message: `Producer epoch ${producerEpoch} is stale; current epoch is ${existing[0].producer_epoch}.`,\n });\n }\n if (producerEpoch > existing[0].producer_epoch) {\n yield* sql`\n UPDATE effect_agent_threads\n SET producer_epoch = ${producerEpoch}\n WHERE thread_id = ${threadId}\n `.pipe(Effect.mapError(storageError(\"advance materialization epoch\")));\n }\n }),\n );\n });\n\n const getThread = Effect.fn(\"DoJournal.getThread\")(function* (threadId: string) {\n const rows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n created_at,\n tail_sequence,\n tail_digest,\n producer_epoch\n FROM effect_agent_threads\n WHERE thread_id = ${threadId}\n `.pipe(Effect.mapError(storageError(\"read thread\")));\n\n return yield* decodeRows(Schema.Array(ThreadRow), \"effect_agent_threads\", threadId, rows);\n });\n\n const append = Effect.fn(\"DoJournal.append\")(function* (\n request: RawAppendRequest,\n ): Effect.fn.Return<RawAppendResult, AppendError> {\n if (\n request.threadId.length > MAX_IDENTIFIER_LENGTH ||\n request.batchId.length > MAX_IDENTIFIER_LENGTH ||\n request.records.some((record) => record.recordId.length > MAX_IDENTIFIER_LENGTH)\n ) {\n return yield* DoStorageError.make({\n operation: \"append canonical batch\",\n message: \"Canonical identifiers exceed the Durable Object storage bounds.\",\n });\n }\n // The platform's ~2 MB per-value limit, enforced typed BEFORE any write (plan §1.2).\n yield* checkValueBound(\"append canonical batch\", request.batchJson);\n yield* checkValueBound(\"append canonical batch\", request.batchDigest);\n yield* checkValueBound(\"append canonical batch\", request.tailDigest);\n yield* Effect.forEach(\n request.records,\n (record) => checkValueBound(\"append canonical record\", record.recordJson),\n { discard: true },\n );\n\n return yield* withWriteTransaction(\"append transaction\")(\n Effect.gen(function* () {\n const recordIds = request.records.map((record) => record.recordId);\n\n if (new Set(recordIds).size !== recordIds.length) {\n return yield* DoAppendConflict.make({\n message: `Batch ${request.batchId} contains duplicate canonical record IDs.`,\n reason: \"record-identity\",\n });\n }\n\n const threadRows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n created_at,\n tail_sequence,\n tail_digest,\n producer_epoch\n FROM effect_agent_threads\n WHERE thread_id = ${request.threadId}\n `.pipe(Effect.mapError(storageError(\"read append tail\")));\n\n const thread = yield* decodeSingleRow(\n Schema.Array(ThreadRow),\n \"effect_agent_threads\",\n request.threadId,\n threadRows,\n );\n\n if (request.producerEpoch !== thread.producer_epoch) {\n return yield* DoFenceRejected.make({\n producerEpoch: request.producerEpoch,\n actualEpoch: thread.producer_epoch,\n message: `Producer epoch ${request.producerEpoch} is not the current epoch ${thread.producer_epoch}.`,\n });\n }\n\n const batchRows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n batch_id,\n first_sequence,\n last_sequence,\n batch_digest,\n tail_digest,\n batch_json\n FROM effect_agent_canonical_batches\n WHERE thread_id = ${request.threadId}\n AND batch_id = ${request.batchId}\n `.pipe(Effect.mapError(storageError(\"read idempotent batch\")));\n\n const batches = yield* decodeRows(\n Schema.Array(BatchRow),\n \"effect_agent_canonical_batches\",\n `${request.threadId}/${request.batchId}`,\n batchRows,\n );\n\n if (batches.length > 1) {\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_batches\",\n rowKey: `${request.threadId}/${request.batchId}`,\n message: \"A canonical batch primary key returned more than one row.\",\n });\n }\n if (batches.length === 1) {\n const existing = batches[0];\n\n if (existing.batch_digest !== request.batchDigest) {\n return yield* DoAppendConflict.make({\n message: `Batch ${request.batchId} already exists with different canonical content.`,\n reason: \"batch-digest\",\n });\n }\n\n return RawAppendResult.make({\n firstSequence: existing.first_sequence,\n lastSequence: existing.last_sequence,\n replayed: true,\n tailDigest: existing.tail_digest,\n });\n }\n\n if (\n request.expectedTailSequence !== thread.tail_sequence ||\n request.expectedTailDigest !== thread.tail_digest\n ) {\n return yield* DoAppendConflict.make({\n message:\n `Expected tail ${request.expectedTailSequence}/${request.expectedTailDigest} ` +\n `but found ${thread.tail_sequence}/${thread.tail_digest}.`,\n reason: \"tail\",\n actualTailSequence: thread.tail_sequence,\n actualTailDigest: thread.tail_digest,\n });\n }\n if (thread.tail_sequence + request.records.length > MAX_RECORDS_PER_THREAD) {\n return yield* DoStorageError.make({\n operation: \"append canonical batch\",\n message: `Thread record limit ${MAX_RECORDS_PER_THREAD} would be exceeded.`,\n });\n }\n\n // Chunked to respect the Durable Object platform's 100-bound-parameter statement\n // limit: a batch may carry up to 256 records.\n const existingRecords: Array<RecordRow> = [];\n\n for (const chunk of chunked(recordIds, MAX_BOUND_PARAMETERS - 10)) {\n const existingRecordRows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n sequence,\n record_id,\n batch_id,\n record_json\n FROM effect_agent_canonical_records\n WHERE thread_id = ${request.threadId}\n AND record_id IN ${sql.in([...chunk])}\n ORDER BY sequence\n `.pipe(Effect.mapError(storageError(\"check canonical record identities\")));\n\n existingRecords.push(\n ...(yield* decodeRows(\n Schema.Array(RecordRow),\n \"effect_agent_canonical_records\",\n `${request.threadId}/record_ids`,\n existingRecordRows,\n )),\n );\n }\n if (existingRecords.length > 0) {\n return yield* DoAppendConflict.make({\n message: `Canonical record ID ${existingRecords[0].record_id} already exists.`,\n reason: \"record-identity\",\n });\n }\n\n const firstSequence = yield* Schema.decodeUnknownEffect(CanonicalSequence)(\n thread.tail_sequence + 1,\n ).pipe(\n Effect.mapError((error) =>\n DoStorageError.make({\n cause: error,\n operation: \"append canonical batch\",\n message: error.message,\n }),\n ),\n );\n\n const lastSequence = yield* Schema.decodeUnknownEffect(CanonicalSequence)(\n firstSequence + request.records.length - 1,\n ).pipe(\n Effect.mapError((error) =>\n DoStorageError.make({\n cause: error,\n operation: \"append canonical batch\",\n message: error.message,\n }),\n ),\n );\n\n yield* sql`\n INSERT INTO effect_agent_canonical_batches (\n thread_id,\n batch_id,\n first_sequence,\n last_sequence,\n batch_digest,\n tail_digest,\n batch_json\n ) VALUES (\n ${request.threadId},\n ${request.batchId},\n ${firstSequence},\n ${lastSequence},\n ${request.batchDigest},\n ${request.tailDigest},\n ${request.batchJson}\n )\n `.pipe(Effect.mapError(storageError(\"insert canonical batch\")));\n yield* failpoint(\"append:after-batch-insert\");\n\n yield* Effect.forEach(\n request.records,\n (record, index) =>\n Effect.gen(function* () {\n yield* sql`\n INSERT INTO effect_agent_canonical_records (\n thread_id,\n sequence,\n record_id,\n batch_id,\n record_json\n ) VALUES (\n ${request.threadId},\n ${firstSequence + index},\n ${record.recordId},\n ${request.batchId},\n ${record.recordJson}\n )\n `.pipe(Effect.mapError(storageError(\"insert canonical record\")));\n yield* failpoint(\"append:after-record-insert\");\n }),\n { discard: true },\n );\n\n yield* sql`\n UPDATE effect_agent_threads\n SET\n tail_sequence = ${lastSequence},\n tail_digest = ${request.tailDigest},\n producer_epoch = ${request.producerEpoch}\n WHERE thread_id = ${request.threadId}\n `.pipe(Effect.mapError(storageError(\"advance thread tail\")));\n yield* failpoint(\"append:after-tail-update\");\n\n return RawAppendResult.make({\n firstSequence,\n lastSequence,\n replayed: false,\n tailDigest: request.tailDigest,\n });\n }),\n );\n });\n\n const read = Effect.fn(\"DoJournal.read\")(function* (request: RawReadRequest) {\n // Capture membership without retaining payloads. Append-only sequences keep each later\n // payload query inside this snapshot, even when new records arrive during consumption.\n const planRows = yield* sql<Record<string, unknown>>`\n SELECT\n sequence,\n length(CAST(record_json AS BLOB)) AS record_json_bytes\n FROM effect_agent_canonical_records\n WHERE thread_id = ${request.threadId}\n AND sequence > ${request.fromSequenceExclusive}\n ORDER BY sequence\n LIMIT ${request.limit}\n `.pipe(Effect.mapError(storageError(\"read canonical records\")));\n\n const plan = yield* decodeRows(\n Schema.Array(ReadPlanRow),\n \"effect_agent_canonical_records\",\n `${request.threadId}>${request.fromSequenceExclusive}`,\n planRows,\n );\n\n const mismatch = () =>\n DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_records\",\n rowKey: `${request.threadId}>${request.fromSequenceExclusive}`,\n message: \"Canonical read membership, sequence, or payload size changed from its read plan.\",\n });\n\n if (plan.length > request.limit) return yield* mismatch();\n\n const pages: Array<ReadPage> = [];\n let page: ReadPage | undefined;\n let pageBytes = 0;\n let previousSequence = request.fromSequenceExclusive;\n\n for (const row of plan) {\n if (row.sequence !== previousSequence + 1) return yield* mismatch();\n previousSequence = row.sequence;\n if (page === undefined || pageBytes + row.record_json_bytes > MAX_READ_PAGE_JSON_BYTES) {\n page = [row];\n pages.push(page);\n pageBytes = row.record_json_bytes;\n } else {\n page.push(row);\n pageBytes += row.record_json_bytes;\n }\n }\n\n const readPage = Effect.fn(\"DoJournal.readPage\")(function* (page: ReadPage) {\n const rows = yield* sql<Record<string, unknown>>`\n SELECT thread_id, sequence, record_id, batch_id, record_json\n FROM effect_agent_canonical_records\n WHERE thread_id = ${request.threadId}\n AND sequence >= ${page[0].sequence}\n AND sequence <= ${page[page.length - 1].sequence}\n ORDER BY sequence\n `.pipe(Effect.mapError(storageError(\"read canonical records\")));\n\n const decoded = yield* decodeRows(\n Schema.Array(RecordRow),\n \"effect_agent_canonical_records\",\n `${request.threadId}/${page[0].sequence}`,\n rows,\n );\n\n if (\n decoded.length !== page.length ||\n decoded.some(\n (row, index) =>\n row.thread_id !== request.threadId ||\n row.sequence !== page[index].sequence ||\n storedTextBytes(row.record_json) !== page[index].record_json_bytes,\n )\n ) {\n return yield* mismatch();\n }\n\n return decoded;\n });\n\n return {\n count: plan.length,\n records: Stream.fromIterable(pages).pipe(\n Stream.flatMap((page) => Stream.fromIterableEffect(readPage(page))),\n ),\n };\n });\n\n const exportThread = Effect.fn(\"DoJournal.exportThread\")(function* (threadId: string) {\n return yield* sql\n .withTransaction(\n Effect.gen(function* () {\n const threadRows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n created_at,\n tail_sequence,\n tail_digest,\n producer_epoch\n FROM effect_agent_threads\n WHERE thread_id = ${threadId}\n `.pipe(Effect.mapError(storageError(\"export thread\")));\n\n const thread = yield* decodeSingleRow(\n Schema.Array(ThreadRow),\n \"effect_agent_threads\",\n threadId,\n threadRows,\n );\n\n yield* failpoint(\"export:after-thread-read\");\n\n if (thread.tail_sequence > MAX_RECORDS_PER_THREAD)\n return yield* DoStorageError.make({\n operation: \"export thread\",\n message: \"The thread exceeds the current export record limit.\",\n });\n const records: Array<RecordRow> = [];\n let afterSequence = ZERO_SEQUENCE;\n\n while (afterSequence < thread.tail_sequence) {\n const limit = Math.min(1_024, thread.tail_sequence - afterSequence);\n\n const request = RawReadRequest.make({\n threadId,\n fromSequenceExclusive: afterSequence,\n limit,\n });\n\n const plan = yield* read(request);\n const page = yield* Stream.runCollect(plan.records);\n\n if (\n page.length !== limit ||\n page.some((record, index) => record.sequence !== afterSequence + index + 1)\n ) {\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_records\",\n rowKey: threadId,\n message:\n \"The exported canonical prefix is not contiguous through its captured tail.\",\n });\n }\n records.push(...page);\n afterSequence = page[page.length - 1].sequence;\n }\n\n const beyondTail =\n yield* sql`SELECT sequence FROM effect_agent_canonical_records WHERE thread_id=${threadId} AND sequence > ${thread.tail_sequence} LIMIT 1`.pipe(\n Effect.mapError(storageError(\"verify export tail\")),\n );\n\n if (beyondTail.length !== 0)\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_records\",\n rowKey: threadId,\n message: \"Canonical records exist beyond the captured thread tail.\",\n });\n\n return RawThreadExport.make({ thread, records });\n }),\n )\n .pipe(\n Effect.catchTag(\"SqlError\", (error) =>\n Effect.fail(storageError(\"export transaction\")(error)),\n ),\n );\n });\n\n const saveCheckpoint = Effect.fn(\"DoJournal.saveCheckpoint\")(function* (\n checkpoint: RawCheckpoint,\n ): Effect.fn.Return<void, CheckpointError> {\n if (checkpoint.threadId.length > MAX_IDENTIFIER_LENGTH) {\n return yield* DoStorageError.make({\n operation: \"save checkpoint\",\n message: \"Checkpoint identity exceeds the Durable Object storage bounds.\",\n });\n }\n yield* checkValueBound(\"save checkpoint\", checkpoint.checkpointJson);\n yield* withWriteTransaction(\"checkpoint transaction\")(\n Effect.gen(function* () {\n const threadRows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n created_at,\n tail_sequence,\n tail_digest,\n producer_epoch\n FROM effect_agent_threads\n WHERE thread_id = ${checkpoint.threadId}\n `.pipe(Effect.mapError(storageError(\"read checkpoint tail\")));\n\n const thread = yield* decodeSingleRow(\n Schema.Array(ThreadRow),\n \"effect_agent_threads\",\n checkpoint.threadId,\n threadRows,\n );\n\n if (checkpoint.throughSequence > thread.tail_sequence) {\n return yield* DoCheckpointConflict.make({\n message:\n `Checkpoint sequence ${checkpoint.throughSequence} is after canonical tail ` +\n `${thread.tail_sequence}.`,\n });\n }\n\n const checkpointRows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n through_sequence,\n tail_digest,\n checkpoint_json\n FROM effect_agent_checkpoints\n WHERE thread_id = ${checkpoint.threadId}\n AND through_sequence = ${checkpoint.throughSequence}\n `.pipe(Effect.mapError(storageError(\"read idempotent checkpoint\")));\n\n const existing = yield* decodeRows(\n Schema.Array(CheckpointRow),\n \"effect_agent_checkpoints\",\n `${checkpoint.threadId}/${checkpoint.throughSequence}`,\n checkpointRows,\n );\n\n if (existing.length > 1) {\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_checkpoints\",\n rowKey: `${checkpoint.threadId}/${checkpoint.throughSequence}`,\n message: \"A checkpoint primary key returned more than one row.\",\n });\n }\n if (existing.length === 1) {\n if (\n existing[0].tail_digest !== checkpoint.tailDigest ||\n existing[0].checkpoint_json !== checkpoint.checkpointJson\n ) {\n return yield* DoCheckpointConflict.make({\n message: \"A different checkpoint already exists at this canonical sequence.\",\n });\n }\n\n return;\n }\n\n yield* sql`\n INSERT INTO effect_agent_checkpoints (\n thread_id,\n through_sequence,\n tail_digest,\n checkpoint_json\n ) VALUES (\n ${checkpoint.threadId},\n ${checkpoint.throughSequence},\n ${checkpoint.tailDigest},\n ${checkpoint.checkpointJson}\n )\n `.pipe(Effect.mapError(storageError(\"insert checkpoint\")));\n }),\n );\n });\n\n const saveRecoveryCheckpoint = Effect.fn(\"DoJournal.saveRecoveryCheckpoint\")(function* (\n request: SaveRecoveryCheckpointRequest,\n checkpointJson: string,\n ) {\n const { checkpoint } = request;\n\n if (checkpoint.threadId.length > MAX_IDENTIFIER_LENGTH) {\n return yield* DoStorageError.make({\n operation: \"save recovery checkpoint\",\n message: \"Checkpoint identity exceeds the Durable Object storage bounds.\",\n });\n }\n yield* checkValueBound(\"save recovery checkpoint\", checkpointJson);\n // Keep injected waits outside the storage-backed transaction callback.\n yield* failpoint(\"save-recovery-checkpoint:before\");\n yield* withWriteTransaction(\"recovery checkpoint transaction\")(\n Effect.gen(function* () {\n const threads = yield* getThread(checkpoint.threadId);\n const thread = threads[0];\n\n if (thread === undefined)\n return yield* ThreadNotMaterialized.make({ threadId: checkpoint.threadId });\n if (request.producerEpoch !== thread.producer_epoch)\n return yield* FenceRejected.make({\n threadId: checkpoint.threadId,\n actualEpoch: thread.producer_epoch,\n attemptedEpoch: request.producerEpoch,\n });\n if (checkpoint.throughSequence > thread.tail_sequence)\n return yield* CheckpointRejected.make({\n threadId: checkpoint.threadId,\n reason: \"ahead-of-tail\",\n });\n\n const digests =\n checkpoint.throughSequence === 0\n ? [EMPTY_TAIL_DIGEST]\n : yield* getTailDigestAt(checkpoint.threadId, checkpoint.throughSequence);\n\n if (digests.length !== 1 || digests[0] !== checkpoint.tailDigest)\n return yield* CheckpointRejected.make({\n threadId: checkpoint.threadId,\n reason: \"digest-mismatch\",\n });\n\n yield* sql`\n INSERT INTO effect_agent_recovery_checkpoints (thread_id, through_sequence, tail_digest, checkpoint_json)\n VALUES (${checkpoint.threadId}, ${checkpoint.throughSequence}, ${checkpoint.tailDigest}, ${checkpointJson})\n ON CONFLICT (thread_id) DO UPDATE SET\n through_sequence = excluded.through_sequence,\n tail_digest = excluded.tail_digest,\n checkpoint_json = excluded.checkpoint_json\n WHERE excluded.through_sequence >= effect_agent_recovery_checkpoints.through_sequence\n `.pipe(Effect.mapError(storageError(\"save recovery checkpoint\")));\n }),\n );\n yield* failpoint(\"save-recovery-checkpoint:after\");\n });\n\n const loadRecoveryCheckpoint = Effect.fn(\"DoJournal.loadRecoveryCheckpoint\")(function* (\n threadId: string,\n ) {\n const rows = yield* sql<Record<string, unknown>>`\n SELECT thread_id, through_sequence, tail_digest, checkpoint_json\n FROM effect_agent_recovery_checkpoints\n WHERE thread_id = ${threadId}\n `.pipe(Effect.mapError(storageError(\"load recovery checkpoint\")));\n\n return yield* decodeRows(\n Schema.Array(CheckpointRow),\n \"effect_agent_recovery_checkpoints\",\n threadId,\n rows,\n );\n });\n\n const loadCheckpoint = Effect.fn(\"DoJournal.loadCheckpoint\")(function* (\n threadId: string,\n atOrBeforeSequence: CanonicalSequence,\n ) {\n const rows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n through_sequence,\n tail_digest,\n checkpoint_json\n FROM effect_agent_checkpoints\n WHERE thread_id = ${threadId}\n AND through_sequence <= ${atOrBeforeSequence}\n ORDER BY through_sequence DESC\n LIMIT 1\n `.pipe(Effect.mapError(storageError(\"load checkpoint\")));\n\n return yield* decodeRows(\n Schema.Array(CheckpointRow),\n \"effect_agent_checkpoints\",\n `${threadId}<=${atOrBeforeSequence}`,\n rows,\n );\n });\n\n const getTailDigestAt = Effect.fn(\"DoJournal.getTailDigestAt\")(function* (\n threadId: string,\n sequence: CanonicalSequence,\n ) {\n if (sequence === 0) {\n const threads = yield* getThread(threadId);\n\n return threads.length === 0\n ? []\n : [threads[0].tail_sequence === 0 ? threads[0].tail_digest : undefined].filter(\n (value): value is string => value !== undefined,\n );\n }\n\n const rows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n batch_id,\n first_sequence,\n last_sequence,\n batch_digest,\n tail_digest,\n batch_json\n FROM effect_agent_canonical_batches\n WHERE thread_id = ${threadId}\n AND last_sequence = ${sequence}\n `.pipe(Effect.mapError(storageError(\"read canonical digest at sequence\")));\n\n const batches = yield* decodeRows(\n Schema.Array(BatchRow),\n \"effect_agent_canonical_batches\",\n `${threadId}/${sequence}`,\n rows,\n );\n\n return batches.map((batch) => batch.tail_digest);\n });\n\n const scanStoredPayloads = Effect.fn(\"DoJournal.scanStoredPayloads\")(function* () {\n return yield* sql\n .withTransaction(\n Effect.gen(function* () {\n const threads = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n created_at,\n tail_sequence,\n tail_digest,\n producer_epoch\n FROM effect_agent_threads\n ORDER BY thread_id\n `.pipe(Effect.mapError(storageError(\"scan threads\")));\n\n const batches = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n batch_id,\n first_sequence,\n last_sequence,\n batch_digest,\n tail_digest,\n batch_json\n FROM effect_agent_canonical_batches\n ORDER BY thread_id, first_sequence\n `.pipe(Effect.mapError(storageError(\"scan canonical batches\")));\n\n const records = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n sequence,\n record_id,\n batch_id,\n record_json\n FROM effect_agent_canonical_records\n ORDER BY thread_id, sequence\n `.pipe(Effect.mapError(storageError(\"scan canonical records\")));\n\n const checkpoints = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n through_sequence,\n tail_digest,\n checkpoint_json\n FROM effect_agent_checkpoints\n ORDER BY thread_id, through_sequence\n `.pipe(Effect.mapError(storageError(\"scan checkpoints\")));\n\n return {\n threads: yield* decodeRows(\n Schema.Array(ThreadRow),\n \"effect_agent_threads\",\n \"startup_scan\",\n threads,\n ),\n batches: yield* decodeRows(\n Schema.Array(BatchRow),\n \"effect_agent_canonical_batches\",\n \"startup_scan\",\n batches,\n ),\n records: yield* decodeRows(\n Schema.Array(RecordRow),\n \"effect_agent_canonical_records\",\n \"startup_scan\",\n records,\n ),\n checkpoints: yield* decodeRows(\n Schema.Array(CheckpointRow),\n \"effect_agent_checkpoints\",\n \"startup_scan\",\n checkpoints,\n ),\n };\n }),\n )\n .pipe(\n Effect.catchTag(\"SqlError\", (error) =>\n Effect.fail(storageError(\"startup scan transaction\")(error)),\n ),\n );\n });\n\n return {\n append,\n checkValueBound,\n exportThread,\n getThread,\n getTailDigestAt,\n loadCheckpoint,\n loadRecoveryCheckpoint,\n saveRecoveryCheckpoint,\n materialize,\n read,\n saveCheckpoint,\n scanStoredPayloads,\n withWriteTransaction,\n } as const;\n};\n\nexport type DoJournal = ReturnType<typeof makeJournal>;\n\nexport const initializeDoJournal = ensureCurrentStorage;\n"],"mappings":"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A,SAAS,OAAO,KAAK;AACvB,CAAC,CACH,CACF,CACJ;;AAGA,MAAa,kBAAkB,OAAO,IAElC,QACA,OACA,QACA,SAEA,WAAW,QAAQ,OAAO,QAAQ,IAAI,CAAC,CAAC,KACtC,OAAO,SAAS,YACd,QAAQ,WAAW,IACf,OAAO,QAAQ,QAAQ,EAAE,IACzB,OAAO,KACL,yBAAyB,KAAK;CAC5B;CACA;CACA,SAAS,sCAAsC,QAAQ,OAAO;AAChE,CAAC,CACH,CACN,CACF,CACJ;;AAGA,MAAM,qBAAqB;CACzB,sBAAsB;EACpB;EACA;EACA;EACA;EACA;CACF;CACA,gCAAgC;EAC9B;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,gCAAgC;EAAC;EAAa;EAAY;EAAa;EAAY;CAAa;CAChG,0BAA0B;EAAC;EAAa;EAAoB;EAAe;CAAiB;CAC5F,0BAA0B;EACxB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,mCAAmC;EACjC;EACA;EACA;EACA;EACA;EACA;CACF;CACA,uBAAuB;EACrB;EACA;EACA;EACA;EACA;EACA;CACF;CACA,sCAAsC;EACpC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,4BAA4B;EAC1B;EACA;EACA;EACA;EACA;CACF;CACA,iCAAiC;EAC/B;EACA;EACA;EACA;EACA;EACA;CACF;CACA,kCAAkC;EAChC;EACA;EACA;EACA;EACA;EACA;CACF;CACA,iCAAiC;EAC/B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,mBAAmB,CAAC,OAAO,OAAO;CAClC,gCAAgC;EAC9B;EACA;EACA;EACA;CACF;AACF;AAEA,MAAM,yBAAyB,OAAO,GAAG,kCAAkC,CAAC,CAAC,WAC3E,SACA;CACA,MAAM,MAAM,OAAO,UAAU;CAsB7B,MAAM,kBAAkB;EACtB,GApBA,YAAY,IACR,qBACA;GACE,GAAG;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"}
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@effect-agent/storage-cloudflare","version":"0.1.0-beta.79","dependencies":{"@effect-agent/core":"0.1.0-beta.79","@effect-agent/thread":"0.1.0-beta.79","@effect/platform-browser":"4.0.0-rc.112","@effect/sql-sqlite-do":"4.0.0-rc.112"},"devDependencies":{"@cloudflare/vitest-pool-workers":"0.21.3","@cloudflare/workers-types":"5.20260825.1","@effect-agent/testing":"0.1.0-beta.79","@effect/vitest":"4.0.0-rc.112","effect":"4.0.0-rc.112","typescript":"7.0.2","vite-plus":"0.3.0","vitest":"4.1.11"},"peerDependencies":{"effect":"^4.0.0-rc.112"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./DoMemoryStore":{"types":"./dist/DoMemoryStore.d.mts","default":"./dist/DoMemoryStore.mjs"},"./DoScheduleStore":{"types":"./dist/DoScheduleStore.d.mts","default":"./dist/DoScheduleStore.mjs"},"./DoStorageConfig":{"types":"./dist/DoStorageConfig.d.mts","default":"./dist/DoStorageConfig.mjs"},"./DoStorageError":{"types":"./dist/DoStorageError.d.mts","default":"./dist/DoStorageError.mjs"},"./DoStorageFailpoint":{"types":"./dist/DoStorageFailpoint.d.mts","default":"./dist/DoStorageFailpoint.mjs"},"./DoStorageVersion":{"types":"./dist/DoStorageVersion.d.mts","default":"./dist/DoStorageVersion.mjs"},"./DoSubmissionLedger":{"types":"./dist/DoSubmissionLedger.d.mts","default":"./dist/DoSubmissionLedger.mjs"},"./DoSubscriptionStore":{"types":"./dist/DoSubscriptionStore.d.mts","default":"./dist/DoSubscriptionStore.mjs"},"./DoThreadStore":{"types":"./dist/DoThreadStore.d.mts","default":"./dist/DoThreadStore.mjs"},"./MemoryProtocol":{"types":"./dist/MemoryProtocol.d.mts","default":"./dist/MemoryProtocol.mjs"},"./PortProtocol":{"types":"./dist/PortProtocol.d.mts","default":"./dist/PortProtocol.mjs"},"./PortRouting":{"types":"./dist/PortRouting.d.mts","default":"./dist/PortRouting.mjs"},"./testing/DoStorageFailpointTesting":{"types":"./dist/DoStorageFailpointTesting.d.mts","default":"./dist/DoStorageFailpointTesting.mjs"},"./DoMessageDeliveryStore":{"types":"./dist/DoMessageDeliveryStore.d.mts","default":"./dist/DoMessageDeliveryStore.mjs"}},"description":"Durable Object SQLite storage adapters and the routed port protocol for Effect Agent on Cloudflare.","license":"MIT","repository":{"type":"git","url":"git+https://github.com/danieljvdm/effect-agent.git","directory":"packages/storage-cloudflare"},"files":["dist","src"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json"}}
1
+ {"name":"@effect-agent/storage-cloudflare","version":"0.1.0-beta.80","dependencies":{"@effect-agent/core":"0.1.0-beta.80","@effect-agent/thread":"0.1.0-beta.80","@effect/platform-browser":"4.0.0-rc.112","@effect/sql-sqlite-do":"4.0.0-rc.112"},"devDependencies":{"@cloudflare/vitest-pool-workers":"0.21.3","@cloudflare/workers-types":"5.20260825.1","@effect-agent/testing":"0.1.0-beta.80","@effect/vitest":"4.0.0-rc.112","effect":"4.0.0-rc.112","typescript":"7.0.2","vite-plus":"0.3.0","vitest":"4.1.11"},"peerDependencies":{"effect":"^4.0.0-rc.112"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./DoMemoryStore":{"types":"./dist/DoMemoryStore.d.mts","default":"./dist/DoMemoryStore.mjs"},"./DoScheduleStore":{"types":"./dist/DoScheduleStore.d.mts","default":"./dist/DoScheduleStore.mjs"},"./DoStorageConfig":{"types":"./dist/DoStorageConfig.d.mts","default":"./dist/DoStorageConfig.mjs"},"./DoStorageError":{"types":"./dist/DoStorageError.d.mts","default":"./dist/DoStorageError.mjs"},"./DoStorageFailpoint":{"types":"./dist/DoStorageFailpoint.d.mts","default":"./dist/DoStorageFailpoint.mjs"},"./DoStorageVersion":{"types":"./dist/DoStorageVersion.d.mts","default":"./dist/DoStorageVersion.mjs"},"./DoSubmissionLedger":{"types":"./dist/DoSubmissionLedger.d.mts","default":"./dist/DoSubmissionLedger.mjs"},"./DoSubscriptionStore":{"types":"./dist/DoSubscriptionStore.d.mts","default":"./dist/DoSubscriptionStore.mjs"},"./DoThreadStore":{"types":"./dist/DoThreadStore.d.mts","default":"./dist/DoThreadStore.mjs"},"./MemoryProtocol":{"types":"./dist/MemoryProtocol.d.mts","default":"./dist/MemoryProtocol.mjs"},"./PortProtocol":{"types":"./dist/PortProtocol.d.mts","default":"./dist/PortProtocol.mjs"},"./PortRouting":{"types":"./dist/PortRouting.d.mts","default":"./dist/PortRouting.mjs"},"./testing/DoStorageFailpointTesting":{"types":"./dist/DoStorageFailpointTesting.d.mts","default":"./dist/DoStorageFailpointTesting.mjs"},"./DoMessageDeliveryStore":{"types":"./dist/DoMessageDeliveryStore.d.mts","default":"./dist/DoMessageDeliveryStore.mjs"}},"description":"Durable Object SQLite storage adapters and the routed port protocol for Effect Agent on Cloudflare.","license":"MIT","repository":{"type":"git","url":"git+https://github.com/danieljvdm/effect-agent.git","directory":"packages/storage-cloudflare"},"files":["dist","src"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json"}}
@@ -151,11 +151,11 @@ export class ThreadPortTransport extends Context.Service<
151
151
  /** Construction options shared by both routed port Layers. */
152
152
  export interface RoutedPortOptions {
153
153
  /**
154
- * The Thread this Durable Object owns (the Object identity rule is
155
- * `namespace.idFromName(threadId)`). Requests addressed here execute on the local
156
- * facet; requests addressed anywhere else route through the transport or fail fast typed.
154
+ * Decide whether this physical owner stores the addressed logical Thread. Local
155
+ * requests use the same SQLite facets; foreign requests use the transport or fail
156
+ * fast typed. The predicate determines placement, never caller authorization.
157
157
  */
158
- readonly localThreadId: ThreadId;
158
+ readonly ownsThread: (threadId: ThreadId) => boolean;
159
159
  }
160
160
 
161
161
  /** Where one port request must execute. */
@@ -175,7 +175,7 @@ const LOCAL: RouteTarget = { _tag: "local" };
175
175
  * refused them at admission, so they cannot name any stored row anywhere.
176
176
  */
177
177
  const routableSubmissionTarget = (
178
- localThreadId: ThreadId,
178
+ ownsThread: RoutedPortOptions["ownsThread"],
179
179
  ): ((operation: string, submissionId: string) => Effect.Effect<RouteTarget, LedgerError>) =>
180
180
  Effect.fn("DoPortRouting.routableSubmissionTarget")(function* (
181
181
  operation: string,
@@ -196,10 +196,10 @@ const routableSubmissionTarget = (
196
196
  if (!UUID_HEAD_PATTERN.test(submissionId.slice(0, separator))) return LOCAL;
197
197
  const tail = submissionId.slice(separator + 1);
198
198
 
199
- if (tail === localThreadId) return LOCAL;
200
-
201
199
  return yield* decodeThreadId(tail).pipe(
202
- Effect.map((threadId): RouteTarget => ({ _tag: "foreign", threadId })),
200
+ Effect.map((threadId): RouteTarget =>
201
+ ownsThread(threadId) ? LOCAL : { _tag: "foreign", threadId },
202
+ ),
203
203
  Effect.orElseSucceed(() => LOCAL),
204
204
  );
205
205
  });
@@ -261,7 +261,7 @@ const makeRoutedLedgerServices = Effect.fn("DoPortRouting.makeRoutedLedgerServic
261
261
  const local = yield* SubmissionLedger;
262
262
  const transport = yield* ThreadPortTransport;
263
263
  const transportCall: TransportCall = makeTransportCall(transport);
264
- const submissionTarget = routableSubmissionTarget(options.localThreadId);
264
+ const submissionTarget = routableSubmissionTarget(options.ownsThread);
265
265
 
266
266
  const routeFailure =
267
267
  (operation: string, target: string) =>
@@ -476,7 +476,7 @@ const makeRoutedLedgerServices = Effect.fn("DoPortRouting.makeRoutedLedgerServic
476
476
  capabilities: local.capabilities,
477
477
 
478
478
  admit: (request) =>
479
- request.threadId === options.localThreadId
479
+ options.ownsThread(request.threadId)
480
480
  ? local.admit(request)
481
481
  : foreignLedgerCall(
482
482
  "ledger admit",
@@ -510,7 +510,7 @@ const makeRoutedLedgerServices = Effect.fn("DoPortRouting.makeRoutedLedgerServic
510
510
  : foreignLookupById("ledger lookup", target.threadId, request.submissionId),
511
511
  ),
512
512
  )
513
- : request.threadId === options.localThreadId
513
+ : options.ownsThread(request.threadId)
514
514
  ? local.lookup(request)
515
515
  : foreignLedgerCall(
516
516
  "ledger lookup",
@@ -525,7 +525,7 @@ const makeRoutedLedgerServices = Effect.fn("DoPortRouting.makeRoutedLedgerServic
525
525
  ),
526
526
 
527
527
  resolveAdmission: (request) =>
528
- request.threadId === options.localThreadId
528
+ options.ownsThread(request.threadId)
529
529
  ? local.resolveAdmission(request)
530
530
  : resolveForeignAdmission(request.threadId, request),
531
531
 
@@ -562,12 +562,12 @@ const makeRoutedLedgerServices = Effect.fn("DoPortRouting.makeRoutedLedgerServic
562
562
  // Every operation below is lane-local by construction (plan §1.3): a foreign address is
563
563
  // an out-of-contract call and fails fast typed instead of being quietly distributed.
564
564
  claim: (request) =>
565
- request.threadId === options.localThreadId
565
+ options.ownsThread(request.threadId)
566
566
  ? local.claim(request)
567
567
  : Effect.fail(crossThreadLedgerError("ledger claim", request.threadId)),
568
568
 
569
569
  claimJoining: (request) =>
570
- request.threadId === options.localThreadId
570
+ options.ownsThread(request.threadId)
571
571
  ? local.claimJoining(request)
572
572
  : Effect.fail(crossThreadLedgerError("ledger claim joining", request.threadId)),
573
573
 
@@ -793,7 +793,7 @@ const makeRoutedStoreServices = Effect.fn("DoPortRouting.makeRoutedStoreServices
793
793
 
794
794
  const routed = ThreadStore.of({
795
795
  materialize: (request) =>
796
- request.threadId === options.localThreadId
796
+ options.ownsThread(request.threadId)
797
797
  ? local.materialize(request)
798
798
  : foreignStoreCall(
799
799
  "thread materialize",
@@ -804,7 +804,7 @@ const makeRoutedStoreServices = Effect.fn("DoPortRouting.makeRoutedStoreServices
804
804
  ).pipe(Effect.asVoid),
805
805
 
806
806
  append: (request) =>
807
- request.threadId === options.localThreadId
807
+ options.ownsThread(request.threadId)
808
808
  ? local.append(request)
809
809
  : foreignStoreCall(
810
810
  "thread append",
@@ -815,7 +815,7 @@ const makeRoutedStoreServices = Effect.fn("DoPortRouting.makeRoutedStoreServices
815
815
  ).pipe(Effect.map((reply) => reply.result)),
816
816
 
817
817
  read: (request) =>
818
- request.threadId === options.localThreadId
818
+ options.ownsThread(request.threadId)
819
819
  ? local.read(request)
820
820
  : Stream.unwrap(
821
821
  foreignStoreCall(
@@ -828,7 +828,7 @@ const makeRoutedStoreServices = Effect.fn("DoPortRouting.makeRoutedStoreServices
828
828
  ),
829
829
 
830
830
  inspectTail: (request) =>
831
- request.threadId === options.localThreadId
831
+ options.ownsThread(request.threadId)
832
832
  ? local.inspectTail(request)
833
833
  : foreignStoreCall(
834
834
  "thread inspect tail",
@@ -839,7 +839,7 @@ const makeRoutedStoreServices = Effect.fn("DoPortRouting.makeRoutedStoreServices
839
839
  ).pipe(Effect.map((reply) => reply.tail)),
840
840
 
841
841
  export: (request) =>
842
- request.threadId === options.localThreadId
842
+ options.ownsThread(request.threadId)
843
843
  ? local.export(request)
844
844
  : foreignStoreCall(
845
845
  "thread export",
@@ -853,7 +853,7 @@ const makeRoutedStoreServices = Effect.fn("DoPortRouting.makeRoutedStoreServices
853
853
  // is materialize/append/read/inspectTail/export. Recovery cache misses can fall back
854
854
  // to those canonical reads, including when the cache belongs to a foreign Object.
855
855
  observe: (request) =>
856
- request.threadId === options.localThreadId
856
+ options.ownsThread(request.threadId)
857
857
  ? local.observe(request)
858
858
  : Stream.unwrap(Effect.fail(crossThreadStoreError("thread observe", request.threadId))),
859
859
 
@@ -862,7 +862,7 @@ const makeRoutedStoreServices = Effect.fn("DoPortRouting.makeRoutedStoreServices
862
862
  : {
863
863
  recoveryCheckpoints: {
864
864
  save: (request) =>
865
- request.checkpoint.threadId === options.localThreadId
865
+ options.ownsThread(request.checkpoint.threadId)
866
866
  ? recoveryCheckpoints.save(request)
867
867
  : Effect.fail(
868
868
  crossThreadStoreError(
@@ -871,7 +871,7 @@ const makeRoutedStoreServices = Effect.fn("DoPortRouting.makeRoutedStoreServices
871
871
  ),
872
872
  ),
873
873
  load: (request) =>
874
- request.threadId === options.localThreadId
874
+ options.ownsThread(request.threadId)
875
875
  ? recoveryCheckpoints.load(request)
876
876
  : Effect.succeed(Option.none()),
877
877
  },
@@ -881,13 +881,13 @@ const makeRoutedStoreServices = Effect.fn("DoPortRouting.makeRoutedStoreServices
881
881
  : {
882
882
  checkpoints: {
883
883
  save: (request) =>
884
- request.checkpoint.threadId === options.localThreadId
884
+ options.ownsThread(request.checkpoint.threadId)
885
885
  ? checkpoints.save(request)
886
886
  : Effect.fail(
887
887
  crossThreadStoreError("thread save checkpoint", request.checkpoint.threadId),
888
888
  ),
889
889
  load: (request) =>
890
- request.threadId === options.localThreadId
890
+ options.ownsThread(request.threadId)
891
891
  ? checkpoints.load(request)
892
892
  : Effect.fail(crossThreadStoreError("thread load checkpoint", request.threadId)),
893
893
  },
@@ -474,7 +474,13 @@ const ensureCurrentStorage = Effect.fn("DoJournal.ensureCurrentStorage")(functio
474
474
  });
475
475
  }
476
476
 
477
- yield* SqliteMigrator.run({ loader: doMigrations }).pipe(
477
+ yield* SqliteMigrator.run({
478
+ loader: doMigrations,
479
+ // An application can share this SQL client and own its own migration history.
480
+ // Keep bookkeeping outside effect_agent_% so interrupted unversioned schemas
481
+ // still fail the ambiguity check above.
482
+ table: "effect_sql_migrations_agent_threads",
483
+ }).pipe(
478
484
  // SqliteMigrator depends on the generic client supplied by this adapter. The concrete
479
485
  // Durable Object client is kept at the outer Layer boundary.
480
486
  Effect.provideService(SqlClient.SqlClient, sql),
@@ -1 +0,0 @@
1
- {"version":3,"file":"do-journal-DnzUmhPA.mjs","names":[],"sources":["../src/internal/do-journal.ts"],"sourcesContent":["import { EMPTY_TAIL_DIGEST } from \"@effect-agent/thread/Digest\";\nimport { CanonicalSequence, ProducerEpoch } from \"@effect-agent/thread/Records\";\nimport { checkV2ThreadLayout } from \"@effect-agent/thread/SqlStorageV2Upgrade\";\nimport {\n MAX_THREAD_EXPORT_RECORDS,\n CheckpointRejected,\n FenceRejected,\n ThreadNotMaterialized,\n type SaveRecoveryCheckpointRequest,\n} from \"@effect-agent/thread/ThreadStore\";\nimport { SqliteMigrator } from \"@effect/sql-sqlite-do\";\nimport { Effect, Schema, Stream } from \"effect\";\nimport * as SqlClient from \"effect/unstable/sql/SqlClient\";\nimport { SqlError } from \"effect/unstable/sql/SqlError\";\n\nimport {\n type DoStorageFailpointError,\n DoAppendConflict,\n DoCheckpointConflict,\n DoFenceRejected,\n DoStorageCompatibilityError,\n DoStorageCorruptionError,\n DoStorageError,\n DoValueBoundExceeded,\n type DoStorageFailpointLocation,\n} from \"../DoStorageError.ts\";\nimport { createMessageDeliveryTables } from \"./message-delivery-schema.ts\";\nimport { CurrentDoStorageVersion, createNonterminalIndex, doMigrations } from \"./migrations.ts\";\nimport { createRecoveryCheckpointTable } from \"./recovery-checkpoint-schema.ts\";\n\n/**\n * Static schema ceiling for stored text columns. Writes are bounded in BYTES by the\n * configured `maxStoredValueBytes` (always ≤ 2,000,000); UTF-8 byte length is never smaller\n * than UTF-16 string length, so any value that passed the byte bound also passes this\n * decode-side character ceiling.\n */\nconst BoundedStoredText = Schema.String.check(Schema.isMaxLength(2_000_000));\nconst BoundedIdentifier = Schema.NonEmptyString.check(Schema.isMaxLength(1024));\nconst MAX_RECORDS_PER_THREAD = MAX_THREAD_EXPORT_RECORDS;\nconst ZERO_SEQUENCE = Schema.decodeSync(CanonicalSequence)(0);\nconst MAX_IDENTIFIER_LENGTH = 1_024;\nconst MAX_READ_PAGE_JSON_BYTES = 4 * 1024 * 1024;\n/** Durable Object SQL storage allows at most 100 bound parameters per statement. */\nconst MAX_BOUND_PARAMETERS = 100;\nconst isSqlError = Schema.is(SqlError);\n\nconst storedTextBytes = (value: string): number => new TextEncoder().encode(value).byteLength;\n\nconst chunked = <A>(values: ReadonlyArray<A>, size: number): Array<ReadonlyArray<A>> => {\n const chunks: Array<ReadonlyArray<A>> = [];\n\n for (let index = 0; index < values.length; index += size) {\n chunks.push(values.slice(index, index + size));\n }\n\n return chunks;\n};\n\nclass DoMetaRow extends Schema.Class<DoMetaRow>(\"DoMetaRow\")({\n value: Schema.NonEmptyString.check(Schema.isMaxLength(128)),\n}) {}\n\nclass DoNameRow extends Schema.Class<DoNameRow>(\"DoNameRow\")({\n name: BoundedIdentifier,\n}) {}\n\nclass ThreadRow extends Schema.Class<ThreadRow>(\"ThreadRow\")({\n thread_id: BoundedIdentifier,\n created_at: Schema.NonEmptyString.check(Schema.isMaxLength(128)),\n producer_epoch: ProducerEpoch,\n tail_digest: BoundedStoredText,\n tail_sequence: CanonicalSequence,\n}) {}\n\nclass BatchRow extends Schema.Class<BatchRow>(\"BatchRow\")({\n batch_digest: BoundedStoredText,\n batch_id: BoundedIdentifier,\n batch_json: BoundedStoredText,\n thread_id: BoundedIdentifier,\n first_sequence: CanonicalSequence,\n last_sequence: CanonicalSequence,\n tail_digest: BoundedStoredText,\n}) {}\n\nclass RecordRow extends Schema.Class<RecordRow>(\"RecordRow\")({\n batch_id: BoundedIdentifier,\n thread_id: BoundedIdentifier,\n record_id: BoundedIdentifier,\n record_json: BoundedStoredText,\n sequence: CanonicalSequence,\n}) {}\n\nconst ReadPlanRow = Schema.Struct({\n sequence: CanonicalSequence,\n record_json_bytes: Schema.Natural.check(Schema.isLessThanOrEqualTo(MAX_READ_PAGE_JSON_BYTES)),\n});\n\ntype ReadPage = [typeof ReadPlanRow.Type, ...Array<typeof ReadPlanRow.Type>];\n\nclass CheckpointRow extends Schema.Class<CheckpointRow>(\"CheckpointRow\")({\n checkpoint_json: BoundedStoredText,\n thread_id: BoundedIdentifier,\n tail_digest: BoundedStoredText,\n through_sequence: CanonicalSequence,\n}) {}\n\nexport class RawRecord extends Schema.Class<RawRecord>(\n \"@effect-agent/storage-cloudflare/RawRecord\",\n)({\n recordId: BoundedIdentifier,\n recordJson: BoundedStoredText,\n}) {}\n\nexport class RawAppendRequest extends Schema.Class<RawAppendRequest>(\n \"@effect-agent/storage-cloudflare/RawAppendRequest\",\n)({\n batchDigest: BoundedStoredText,\n batchId: BoundedIdentifier,\n batchJson: BoundedStoredText,\n threadId: BoundedIdentifier,\n expectedTailDigest: BoundedStoredText,\n expectedTailSequence: CanonicalSequence,\n producerEpoch: ProducerEpoch,\n records: Schema.NonEmptyArray(RawRecord).check(Schema.isMaxLength(256)),\n tailDigest: BoundedStoredText,\n}) {}\n\nexport class RawAppendResult extends Schema.Class<RawAppendResult>(\n \"@effect-agent/storage-cloudflare/RawAppendResult\",\n)({\n firstSequence: CanonicalSequence,\n lastSequence: CanonicalSequence,\n replayed: Schema.Boolean,\n tailDigest: BoundedStoredText,\n}) {}\n\nexport class RawReadRequest extends Schema.Class<RawReadRequest>(\n \"@effect-agent/storage-cloudflare/RawReadRequest\",\n)({\n threadId: BoundedIdentifier,\n fromSequenceExclusive: CanonicalSequence,\n limit: Schema.Int.check(Schema.isGreaterThan(0), Schema.isLessThanOrEqualTo(1_024)),\n}) {}\n\nexport class RawCheckpoint extends Schema.Class<RawCheckpoint>(\n \"@effect-agent/storage-cloudflare/RawCheckpoint\",\n)({\n checkpointJson: BoundedStoredText,\n threadId: BoundedIdentifier,\n tailDigest: BoundedStoredText,\n throughSequence: CanonicalSequence,\n}) {}\n\nexport class RawThreadExport extends Schema.Class<RawThreadExport>(\n \"@effect-agent/storage-cloudflare/RawThreadExport\",\n)({\n thread: ThreadRow,\n records: Schema.Array(RecordRow),\n}) {}\n\ntype AppendError =\n | DoAppendConflict\n | DoFenceRejected\n | DoStorageCorruptionError\n | DoStorageError\n | DoStorageFailpointError\n | DoValueBoundExceeded;\n\ntype CheckpointError =\n | DoCheckpointConflict\n | DoStorageCorruptionError\n | DoStorageError\n | DoValueBoundExceeded;\n\ntype DoJournalFailpoint = (\n location: DoStorageFailpointLocation,\n) => Effect.Effect<void, DoStorageFailpointError>;\n\nconst noFailpoint: DoJournalFailpoint = () => Effect.void;\n\nconst storageError =\n (operation: string) =>\n (error: SqlError): DoStorageError =>\n DoStorageError.make({\n cause: error,\n operation,\n message: error.message,\n });\n\n/** Decode raw Durable Object SQLite rows against a Schema, reporting failures as typed corruption. */\nexport const decodeRows = Effect.fn(\n <A, I>(\n schema: Schema.Codec<ReadonlyArray<A>, ReadonlyArray<I>>,\n table: string,\n rowKey: string,\n rows: unknown,\n ): Effect.Effect<ReadonlyArray<A>, DoStorageCorruptionError> =>\n Schema.decodeUnknownEffect(schema)(rows).pipe(\n Effect.mapError((error) =>\n DoStorageCorruptionError.make({\n table,\n rowKey,\n message: String(error),\n }),\n ),\n ),\n);\n\n/** Decode exactly one raw row against a Schema, reporting failures as typed corruption. */\nexport const decodeSingleRow = Effect.fn(\n <A, I>(\n schema: Schema.Codec<ReadonlyArray<A>, ReadonlyArray<I>>,\n table: string,\n rowKey: string,\n rows: unknown,\n ): Effect.Effect<A, DoStorageCorruptionError> =>\n decodeRows(schema, table, rowKey, rows).pipe(\n Effect.flatMap((decoded) =>\n decoded.length === 1\n ? Effect.succeed(decoded[0])\n : Effect.fail(\n DoStorageCorruptionError.make({\n table,\n rowKey,\n message: `Expected exactly one row but found ${decoded.length}.`,\n }),\n ),\n ),\n ),\n);\n\n/** Column inventory of the supported v3 predecessor, independent of physical column order. */\nconst predecessorColumns = {\n effect_agent_threads: [\n \"thread_id\",\n \"created_at\",\n \"tail_sequence\",\n \"tail_digest\",\n \"producer_epoch\",\n ],\n effect_agent_canonical_batches: [\n \"thread_id\",\n \"batch_id\",\n \"first_sequence\",\n \"last_sequence\",\n \"batch_digest\",\n \"tail_digest\",\n \"batch_json\",\n ],\n effect_agent_canonical_records: [\"thread_id\", \"sequence\", \"record_id\", \"batch_id\", \"record_json\"],\n effect_agent_checkpoints: [\"thread_id\", \"through_sequence\", \"tail_digest\", \"checkpoint_json\"],\n effect_agent_submissions: [\n \"submission_id\",\n \"thread_id\",\n \"queue_sequence\",\n \"principal\",\n \"idempotency_key\",\n \"agent_id\",\n \"agent_digests_json\",\n \"deployment_id\",\n \"input_json\",\n \"input_digest\",\n \"receipt_id\",\n \"state\",\n \"settled_outcome\",\n \"created_at\",\n \"ready_at\",\n \"input_applied_record_id\",\n \"input_applied_sequence\",\n \"joined_host_submission_id\",\n \"suspended_reason_json\",\n \"suspended_at\",\n \"unknown_reason\",\n \"unknown_tool_call_ids_json\",\n \"parent_submission_id\",\n \"parent_tool_call_id\",\n \"admission_group\",\n \"admission_fence_json\",\n ],\n effect_agent_submission_ownership: [\n \"submission_id\",\n \"attempt_id\",\n \"ownership_token\",\n \"producer_epoch\",\n \"owner_producer_id\",\n \"lease_expires_at\",\n ],\n effect_agent_attempts: [\n \"attempt_id\",\n \"submission_id\",\n \"thread_id\",\n \"owner_producer_id\",\n \"producer_epoch\",\n \"claimed_at\",\n ],\n effect_agent_settlement_reservations: [\n \"submission_id\",\n \"settlement_id\",\n \"outcome\",\n \"record_id\",\n \"record_json\",\n \"record_digest\",\n \"reserved_at\",\n \"finalized_at\",\n ],\n effect_agent_abort_intents: [\n \"submission_id\",\n \"author\",\n \"reason\",\n \"requested_at\",\n \"canonical_record_id\",\n ],\n effect_agent_approval_decisions: [\n \"submission_id\",\n \"tool_call_id\",\n \"decision\",\n \"resolver\",\n \"reason\",\n \"decided_at\",\n ],\n effect_agent_unknown_resolutions: [\n \"submission_id\",\n \"tool_call_id\",\n \"author\",\n \"reason\",\n \"resolution_json\",\n \"resolved_at\",\n ],\n effect_agent_child_reservations: [\n \"reservation_id\",\n \"parent_submission_id\",\n \"parent_tool_call_id\",\n \"child_submission_id\",\n \"status\",\n \"allocation_json\",\n \"allocation_digest\",\n \"accounting_json\",\n \"reserved_at\",\n \"release_began_at\",\n \"released_at\",\n ],\n effect_agent_meta: [\"key\", \"value\"],\n effect_agent_child_settlements: [\n \"parent_submission_id\",\n \"child_submission_id\",\n \"child_outcome\",\n \"recorded_at\",\n ],\n} as const;\n\nconst checkPredecessorLayout = Effect.fn(\"DoJournal.checkPredecessorLayout\")(function* (\n version: 3 | 4 | 5,\n) {\n const sql = yield* SqlClient.SqlClient;\n\n const messageColumns =\n version === 3\n ? predecessorColumns\n : {\n ...predecessorColumns,\n effect_agent_submissions: [\n ...predecessorColumns.effect_agent_submissions,\n \"worker_admission_json\",\n \"message_admission_json\",\n ],\n effect_agent_message_deliveries: [\n \"owner_thread_id\",\n \"message_id\",\n \"version\",\n \"state\",\n \"deadline_at_millis\",\n \"record_json\",\n ],\n };\n\n const expectedColumns = {\n ...messageColumns,\n ...(version === 5\n ? {\n effect_agent_recovery_checkpoints: [\n \"thread_id\",\n \"through_sequence\",\n \"tail_digest\",\n \"checkpoint_json\",\n ],\n }\n : {}),\n };\n\n for (const [table, expected] of Object.entries(expectedColumns)) {\n const columns = yield* decodeRows(\n Schema.Array(Schema.Struct({ name: BoundedIdentifier })),\n table,\n \"schema\",\n yield* sql.unsafe(`PRAGMA table_info(${table})`),\n );\n\n const names = new Set<string>(expected);\n\n if (columns.length !== names.size || columns.some((column) => !names.has(column.name)))\n return yield* DoStorageCompatibilityError.make({\n actualVersion: version,\n supportedVersion: CurrentDoStorageVersion,\n message: `The v${version} ${table} columns do not match the supported predecessor; no upgrade was committed.`,\n });\n }\n});\n\nconst REQUIRED_TABLES = [\n \"effect_agent_abort_intents\",\n \"effect_agent_approval_decisions\",\n \"effect_agent_attempts\",\n \"effect_agent_canonical_batches\",\n \"effect_agent_canonical_records\",\n \"effect_agent_checkpoints\",\n \"effect_agent_child_reservations\",\n \"effect_agent_child_settlements\",\n \"effect_agent_threads\",\n \"effect_agent_meta\",\n \"effect_agent_settlement_reservations\",\n \"effect_agent_submission_ownership\",\n \"effect_agent_submissions\",\n \"effect_agent_unknown_resolutions\",\n] as const;\n\n/**\n * Supported-predecessor or fresh storage gate (DEPLOY-008) over `effect_agent_meta` instead of\n * `PRAGMA user_version` (unverified on Durable Object SQL storage; a meta table is portable\n * regardless). No WAL check (Durable Object storage owns durability and confirms writes\n * through output gates) and no busy timeout (a Durable Object has exactly one writer): the\n * Node machinery those served has no DC analogue and is deliberately absent.\n */\nconst ensureCurrentStorage = Effect.fn(\"DoJournal.ensureCurrentStorage\")(function* (\n sql: SqlClient.SqlClient,\n failpoint: DoJournalFailpoint = noFailpoint,\n maxStoredValueBytes: number,\n) {\n const metaTableRows = yield* sql<Record<string, unknown>>`\n SELECT name\n FROM sqlite_master\n WHERE type = 'table'\n AND name = 'effect_agent_meta'\n `.pipe(Effect.mapError(storageError(\"read storage version table\")));\n\n const metaTables = yield* decodeRows(\n Schema.Array(DoNameRow),\n \"sqlite_master\",\n \"effect_agent_meta\",\n metaTableRows,\n );\n\n if (metaTables.length === 0) {\n const existingRows = yield* sql<Record<string, unknown>>`\n SELECT name\n FROM sqlite_master\n WHERE type = 'table'\n AND name LIKE 'effect_agent_%'\n ORDER BY name\n `.pipe(Effect.mapError(storageError(\"inspect unversioned storage\")));\n\n const existing = yield* decodeRows(\n Schema.Array(DoNameRow),\n \"sqlite_master\",\n \"effect_agent_%\",\n existingRows,\n );\n\n if (existing.length > 0) {\n return yield* DoStorageCompatibilityError.make({\n actualVersion: 0,\n supportedVersion: CurrentDoStorageVersion,\n message:\n \"The Durable Object contains unversioned Effect Agent tables. Refusing to mutate ambiguous stored data; retain it for inspection with its original writer.\",\n });\n }\n\n yield* SqliteMigrator.run({ loader: doMigrations }).pipe(\n // SqliteMigrator depends on the generic client supplied by this adapter. The concrete\n // Durable Object client is kept at the outer Layer boundary.\n Effect.provideService(SqlClient.SqlClient, sql),\n Effect.mapError((error) =>\n DoStorageError.make({\n cause: error,\n operation: \"initialize current storage\",\n message: error.message,\n }),\n ),\n );\n } else {\n const versionRows = yield* sql<Record<string, unknown>>`\n SELECT value\n FROM effect_agent_meta\n WHERE key = 'storage_version'\n `.pipe(Effect.mapError(storageError(\"read storage version\")));\n\n const version = yield* decodeSingleRow(\n Schema.Array(DoMetaRow),\n \"effect_agent_meta\",\n \"storage_version\",\n versionRows,\n );\n\n if (\n version.value === \"2\" ||\n version.value === \"3\" ||\n version.value === \"4\" ||\n version.value === \"5\"\n ) {\n yield* sql\n .withTransaction(\n Effect.gen(function* () {\n const current = yield* sql<{\n value: string;\n }>`SELECT value FROM effect_agent_meta WHERE key='storage_version'`;\n\n if (current.length === 1 && current[0].value === String(CurrentDoStorageVersion))\n return;\n if (\n current.length !== 1 ||\n (current[0].value !== \"2\" &&\n current[0].value !== \"3\" &&\n current[0].value !== \"4\" &&\n current[0].value !== \"5\")\n )\n return yield* DoStorageCompatibilityError.make({\n actualVersion: -1,\n supportedVersion: CurrentDoStorageVersion,\n message: \"Storage version changed while acquiring the upgrade transaction.\",\n });\n\n const required = yield* decodeRows(\n Schema.Array(DoNameRow),\n \"sqlite_master\",\n \"required_tables\",\n yield* sql`SELECT name FROM sqlite_master WHERE type='table' AND name IN ${sql.in([...REQUIRED_TABLES])}`,\n );\n\n if (required.length !== REQUIRED_TABLES.length)\n return yield* DoStorageCompatibilityError.make({\n actualVersion: Number(current[0].value),\n supportedVersion: CurrentDoStorageVersion,\n message:\n \"The predecessor store is missing required tables. Retain the original store for inspection; no upgrade was committed.\",\n });\n\n const recoveryTables =\n yield* sql`SELECT name FROM sqlite_master WHERE type='table' AND name='effect_agent_recovery_checkpoints'`;\n\n if (recoveryTables.length !== (current[0].value === \"5\" ? 1 : 0))\n return yield* DoStorageCompatibilityError.make({\n actualVersion: Number(current[0].value),\n supportedVersion: CurrentDoStorageVersion,\n message:\n \"The predecessor recovery checkpoint storage does not match its version; refusing ambiguous data without mutation.\",\n });\n\n const indexes =\n yield* sql`SELECT name FROM sqlite_master WHERE name='effect_agent_submissions_nonterminal'`;\n\n if (indexes.length !== 0)\n return yield* DoStorageCompatibilityError.make({\n actualVersion: Number(current[0].value),\n supportedVersion: CurrentDoStorageVersion,\n message:\n \"The predecessor already contains the nonterminal index; refusing ambiguous storage without mutation.\",\n });\n if (current[0].value === \"2\") {\n yield* checkV2ThreadLayout();\n for (const statement of [\n sql`ALTER TABLE effect_agent_submissions ADD COLUMN admission_group TEXT`,\n sql`ALTER TABLE effect_agent_submissions ADD COLUMN admission_fence_json TEXT`,\n sql`CREATE INDEX effect_agent_submissions_group ON effect_agent_submissions (thread_id, admission_group, state)`,\n ]) {\n yield* failpoint(\"upgrade:before-mutation\");\n yield* statement;\n yield* failpoint(\"upgrade:after-mutation\");\n }\n }\n if (current[0].value === \"3\") yield* checkPredecessorLayout(3);\n if (current[0].value === \"4\") yield* checkPredecessorLayout(4);\n if (current[0].value === \"5\") yield* checkPredecessorLayout(5);\n if (current[0].value === \"2\" || current[0].value === \"3\") {\n yield* failpoint(\"upgrade:before-mutation\");\n yield* sql`ALTER TABLE effect_agent_submissions ADD COLUMN worker_admission_json TEXT`;\n yield* failpoint(\"upgrade:after-mutation\");\n yield* failpoint(\"upgrade:before-mutation\");\n yield* sql`ALTER TABLE effect_agent_submissions ADD COLUMN message_admission_json TEXT`;\n yield* failpoint(\"upgrade:after-mutation\");\n yield* failpoint(\"upgrade:before-mutation\");\n yield* createMessageDeliveryTables;\n yield* failpoint(\"upgrade:after-mutation\");\n }\n if (current[0].value !== \"5\") {\n yield* failpoint(\"upgrade:before-mutation\");\n yield* createRecoveryCheckpointTable;\n yield* failpoint(\"upgrade:after-mutation\");\n }\n yield* failpoint(\"upgrade:before-mutation\");\n yield* createNonterminalIndex;\n yield* failpoint(\"upgrade:after-mutation\");\n yield* failpoint(\"upgrade:before-version\");\n yield* sql`UPDATE effect_agent_meta SET value='6' WHERE key='storage_version'`;\n yield* failpoint(\"upgrade:after-version\");\n }),\n )\n .pipe(\n Effect.catchTag(\"DoStorageFailpointError\", (error) =>\n DoStorageError.make({\n cause: error,\n operation: \"upgrade storage\",\n message: error.message,\n }),\n ),\n Effect.catchTag(\"StorageUpgradeError\", (error) =>\n DoStorageCorruptionError.make({\n table: error.table,\n rowKey: error.rowKey,\n message: error.message,\n }),\n ),\n Effect.catchTag(\"SqlError\", storageError(\"upgrade supported thread storage\")),\n );\n } else if (version.value !== String(CurrentDoStorageVersion)) {\n const actualVersion = Number.parseInt(version.value, 10);\n\n return yield* DoStorageCompatibilityError.make({\n actualVersion: Number.isSafeInteger(actualVersion) ? actualVersion : -1,\n supportedVersion: CurrentDoStorageVersion,\n message:\n `The Durable Object uses unsupported storage version ${version.value}; ` +\n `this build supports exactly version ${CurrentDoStorageVersion}. ` +\n \"Only supported v2, v3, v4 and v5 can be upgraded automatically. Keep the original store and use a compatible library version.\",\n });\n }\n }\n\n const requiredRows = yield* sql<Record<string, unknown>>`\n SELECT name\n FROM sqlite_master\n WHERE (type = 'table'\n AND name IN ${sql.in([...REQUIRED_TABLES, \"effect_agent_message_deliveries\", \"effect_agent_recovery_checkpoints\"])}\n ) OR (type = 'index' AND name = 'effect_agent_submissions_nonterminal')\n ORDER BY name\n `.pipe(Effect.mapError(storageError(\"verify storage tables\")));\n\n const required = yield* decodeRows(\n Schema.Array(DoNameRow),\n \"sqlite_master\",\n \"required_tables\",\n requiredRows,\n );\n\n if (required.length !== REQUIRED_TABLES.length + 3) {\n return yield* DoStorageCompatibilityError.make({\n actualVersion: CurrentDoStorageVersion,\n supportedVersion: CurrentDoStorageVersion,\n message:\n \"The Durable Object claims the current format but is missing required tables or its nonterminal index. Retain the original store for inspection.\",\n });\n }\n\n return makeJournal(sql, failpoint, maxStoredValueBytes);\n});\n\nconst makeJournal = (\n sql: SqlClient.SqlClient,\n failpoint: DoJournalFailpoint,\n maxStoredValueBytes: number,\n) => {\n /** Typed pre-write refusal for any single value over the configured byte bound. */\n const checkValueBound = (\n operation: string,\n value: string,\n ): Effect.Effect<void, DoValueBoundExceeded> => {\n const actualBytes = storedTextBytes(value);\n\n return actualBytes > maxStoredValueBytes\n ? Effect.fail(\n DoValueBoundExceeded.make({\n actualBytes,\n maxBytes: maxStoredValueBytes,\n operation,\n }),\n )\n : Effect.void;\n };\n\n /**\n * Runs one journal write transaction on the Durable Object storage-backed\n * `withTransaction` (`ctx.storage.transaction()` under the hood). Within one Durable\n * Object there is exactly ONE writer, so the Node `BEGIN IMMEDIATE` + busy-retry +\n * `SqliteWriteContention` machinery has no analogue here and is deliberately absent.\n * Ownership-token and epoch checks still run INSIDE the transaction, so fencing atomicity\n * (DUR-006) is preserved identically.\n *\n * Journal write transactions are always top level: the Durable Object client rejects\n * nested transactions, so new journal operations must not wrap this helper inside another\n * transaction.\n */\n const withWriteTransaction =\n (operation: string) =>\n <A, E>(effect: Effect.Effect<A, E>): Effect.Effect<A, E | DoStorageError> =>\n sql.withTransaction(effect).pipe(\n Effect.mapError((error) => (isSqlError(error) ? storageError(operation)(error) : error)),\n Effect.withSpan(\"DoJournal.withWriteTransaction\", { attributes: { operation } }),\n );\n\n const materialize = Effect.fn(\"DoJournal.materialize\")(function* (\n threadId: string,\n createdAt: string,\n emptyTailDigest: string,\n producerEpoch: ProducerEpoch,\n ): Effect.fn.Return<\n void,\n DoFenceRejected | DoStorageCorruptionError | DoStorageError | DoValueBoundExceeded\n > {\n if (threadId.length > MAX_IDENTIFIER_LENGTH) {\n return yield* DoStorageError.make({\n operation: \"materialize thread\",\n message: \"Thread identity exceeds the Durable Object storage bounds.\",\n });\n }\n yield* checkValueBound(\"materialize thread\", emptyTailDigest);\n yield* withWriteTransaction(\"materialize transaction\")(\n Effect.gen(function* () {\n const existingRows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n created_at,\n tail_sequence,\n tail_digest,\n producer_epoch\n FROM effect_agent_threads\n WHERE thread_id = ${threadId}\n `.pipe(Effect.mapError(storageError(\"read materialized thread\")));\n\n const existing = yield* decodeRows(\n Schema.Array(ThreadRow),\n \"effect_agent_threads\",\n threadId,\n existingRows,\n );\n\n if (existing.length > 1) {\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_threads\",\n rowKey: threadId,\n message: \"A thread primary key returned more than one row.\",\n });\n }\n if (existing.length === 0) {\n yield* sql`\n INSERT INTO effect_agent_threads (\n thread_id,\n created_at,\n tail_sequence,\n tail_digest,\n producer_epoch\n ) VALUES (\n ${threadId},\n ${createdAt},\n 0,\n ${emptyTailDigest},\n ${producerEpoch}\n )\n `.pipe(Effect.mapError(storageError(\"materialize thread\")));\n\n return;\n }\n if (producerEpoch < existing[0].producer_epoch) {\n return yield* DoFenceRejected.make({\n producerEpoch,\n actualEpoch: existing[0].producer_epoch,\n message: `Producer epoch ${producerEpoch} is stale; current epoch is ${existing[0].producer_epoch}.`,\n });\n }\n if (producerEpoch > existing[0].producer_epoch) {\n yield* sql`\n UPDATE effect_agent_threads\n SET producer_epoch = ${producerEpoch}\n WHERE thread_id = ${threadId}\n `.pipe(Effect.mapError(storageError(\"advance materialization epoch\")));\n }\n }),\n );\n });\n\n const getThread = Effect.fn(\"DoJournal.getThread\")(function* (threadId: string) {\n const rows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n created_at,\n tail_sequence,\n tail_digest,\n producer_epoch\n FROM effect_agent_threads\n WHERE thread_id = ${threadId}\n `.pipe(Effect.mapError(storageError(\"read thread\")));\n\n return yield* decodeRows(Schema.Array(ThreadRow), \"effect_agent_threads\", threadId, rows);\n });\n\n const append = Effect.fn(\"DoJournal.append\")(function* (\n request: RawAppendRequest,\n ): Effect.fn.Return<RawAppendResult, AppendError> {\n if (\n request.threadId.length > MAX_IDENTIFIER_LENGTH ||\n request.batchId.length > MAX_IDENTIFIER_LENGTH ||\n request.records.some((record) => record.recordId.length > MAX_IDENTIFIER_LENGTH)\n ) {\n return yield* DoStorageError.make({\n operation: \"append canonical batch\",\n message: \"Canonical identifiers exceed the Durable Object storage bounds.\",\n });\n }\n // The platform's ~2 MB per-value limit, enforced typed BEFORE any write (plan §1.2).\n yield* checkValueBound(\"append canonical batch\", request.batchJson);\n yield* checkValueBound(\"append canonical batch\", request.batchDigest);\n yield* checkValueBound(\"append canonical batch\", request.tailDigest);\n yield* Effect.forEach(\n request.records,\n (record) => checkValueBound(\"append canonical record\", record.recordJson),\n { discard: true },\n );\n\n return yield* withWriteTransaction(\"append transaction\")(\n Effect.gen(function* () {\n const recordIds = request.records.map((record) => record.recordId);\n\n if (new Set(recordIds).size !== recordIds.length) {\n return yield* DoAppendConflict.make({\n message: `Batch ${request.batchId} contains duplicate canonical record IDs.`,\n reason: \"record-identity\",\n });\n }\n\n const threadRows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n created_at,\n tail_sequence,\n tail_digest,\n producer_epoch\n FROM effect_agent_threads\n WHERE thread_id = ${request.threadId}\n `.pipe(Effect.mapError(storageError(\"read append tail\")));\n\n const thread = yield* decodeSingleRow(\n Schema.Array(ThreadRow),\n \"effect_agent_threads\",\n request.threadId,\n threadRows,\n );\n\n if (request.producerEpoch !== thread.producer_epoch) {\n return yield* DoFenceRejected.make({\n producerEpoch: request.producerEpoch,\n actualEpoch: thread.producer_epoch,\n message: `Producer epoch ${request.producerEpoch} is not the current epoch ${thread.producer_epoch}.`,\n });\n }\n\n const batchRows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n batch_id,\n first_sequence,\n last_sequence,\n batch_digest,\n tail_digest,\n batch_json\n FROM effect_agent_canonical_batches\n WHERE thread_id = ${request.threadId}\n AND batch_id = ${request.batchId}\n `.pipe(Effect.mapError(storageError(\"read idempotent batch\")));\n\n const batches = yield* decodeRows(\n Schema.Array(BatchRow),\n \"effect_agent_canonical_batches\",\n `${request.threadId}/${request.batchId}`,\n batchRows,\n );\n\n if (batches.length > 1) {\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_batches\",\n rowKey: `${request.threadId}/${request.batchId}`,\n message: \"A canonical batch primary key returned more than one row.\",\n });\n }\n if (batches.length === 1) {\n const existing = batches[0];\n\n if (existing.batch_digest !== request.batchDigest) {\n return yield* DoAppendConflict.make({\n message: `Batch ${request.batchId} already exists with different canonical content.`,\n reason: \"batch-digest\",\n });\n }\n\n return RawAppendResult.make({\n firstSequence: existing.first_sequence,\n lastSequence: existing.last_sequence,\n replayed: true,\n tailDigest: existing.tail_digest,\n });\n }\n\n if (\n request.expectedTailSequence !== thread.tail_sequence ||\n request.expectedTailDigest !== thread.tail_digest\n ) {\n return yield* DoAppendConflict.make({\n message:\n `Expected tail ${request.expectedTailSequence}/${request.expectedTailDigest} ` +\n `but found ${thread.tail_sequence}/${thread.tail_digest}.`,\n reason: \"tail\",\n actualTailSequence: thread.tail_sequence,\n actualTailDigest: thread.tail_digest,\n });\n }\n if (thread.tail_sequence + request.records.length > MAX_RECORDS_PER_THREAD) {\n return yield* DoStorageError.make({\n operation: \"append canonical batch\",\n message: `Thread record limit ${MAX_RECORDS_PER_THREAD} would be exceeded.`,\n });\n }\n\n // Chunked to respect the Durable Object platform's 100-bound-parameter statement\n // limit: a batch may carry up to 256 records.\n const existingRecords: Array<RecordRow> = [];\n\n for (const chunk of chunked(recordIds, MAX_BOUND_PARAMETERS - 10)) {\n const existingRecordRows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n sequence,\n record_id,\n batch_id,\n record_json\n FROM effect_agent_canonical_records\n WHERE thread_id = ${request.threadId}\n AND record_id IN ${sql.in([...chunk])}\n ORDER BY sequence\n `.pipe(Effect.mapError(storageError(\"check canonical record identities\")));\n\n existingRecords.push(\n ...(yield* decodeRows(\n Schema.Array(RecordRow),\n \"effect_agent_canonical_records\",\n `${request.threadId}/record_ids`,\n existingRecordRows,\n )),\n );\n }\n if (existingRecords.length > 0) {\n return yield* DoAppendConflict.make({\n message: `Canonical record ID ${existingRecords[0].record_id} already exists.`,\n reason: \"record-identity\",\n });\n }\n\n const firstSequence = yield* Schema.decodeUnknownEffect(CanonicalSequence)(\n thread.tail_sequence + 1,\n ).pipe(\n Effect.mapError((error) =>\n DoStorageError.make({\n cause: error,\n operation: \"append canonical batch\",\n message: error.message,\n }),\n ),\n );\n\n const lastSequence = yield* Schema.decodeUnknownEffect(CanonicalSequence)(\n firstSequence + request.records.length - 1,\n ).pipe(\n Effect.mapError((error) =>\n DoStorageError.make({\n cause: error,\n operation: \"append canonical batch\",\n message: error.message,\n }),\n ),\n );\n\n yield* sql`\n INSERT INTO effect_agent_canonical_batches (\n thread_id,\n batch_id,\n first_sequence,\n last_sequence,\n batch_digest,\n tail_digest,\n batch_json\n ) VALUES (\n ${request.threadId},\n ${request.batchId},\n ${firstSequence},\n ${lastSequence},\n ${request.batchDigest},\n ${request.tailDigest},\n ${request.batchJson}\n )\n `.pipe(Effect.mapError(storageError(\"insert canonical batch\")));\n yield* failpoint(\"append:after-batch-insert\");\n\n yield* Effect.forEach(\n request.records,\n (record, index) =>\n Effect.gen(function* () {\n yield* sql`\n INSERT INTO effect_agent_canonical_records (\n thread_id,\n sequence,\n record_id,\n batch_id,\n record_json\n ) VALUES (\n ${request.threadId},\n ${firstSequence + index},\n ${record.recordId},\n ${request.batchId},\n ${record.recordJson}\n )\n `.pipe(Effect.mapError(storageError(\"insert canonical record\")));\n yield* failpoint(\"append:after-record-insert\");\n }),\n { discard: true },\n );\n\n yield* sql`\n UPDATE effect_agent_threads\n SET\n tail_sequence = ${lastSequence},\n tail_digest = ${request.tailDigest},\n producer_epoch = ${request.producerEpoch}\n WHERE thread_id = ${request.threadId}\n `.pipe(Effect.mapError(storageError(\"advance thread tail\")));\n yield* failpoint(\"append:after-tail-update\");\n\n return RawAppendResult.make({\n firstSequence,\n lastSequence,\n replayed: false,\n tailDigest: request.tailDigest,\n });\n }),\n );\n });\n\n const read = Effect.fn(\"DoJournal.read\")(function* (request: RawReadRequest) {\n // Capture membership without retaining payloads. Append-only sequences keep each later\n // payload query inside this snapshot, even when new records arrive during consumption.\n const planRows = yield* sql<Record<string, unknown>>`\n SELECT\n sequence,\n length(CAST(record_json AS BLOB)) AS record_json_bytes\n FROM effect_agent_canonical_records\n WHERE thread_id = ${request.threadId}\n AND sequence > ${request.fromSequenceExclusive}\n ORDER BY sequence\n LIMIT ${request.limit}\n `.pipe(Effect.mapError(storageError(\"read canonical records\")));\n\n const plan = yield* decodeRows(\n Schema.Array(ReadPlanRow),\n \"effect_agent_canonical_records\",\n `${request.threadId}>${request.fromSequenceExclusive}`,\n planRows,\n );\n\n const mismatch = () =>\n DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_records\",\n rowKey: `${request.threadId}>${request.fromSequenceExclusive}`,\n message: \"Canonical read membership, sequence, or payload size changed from its read plan.\",\n });\n\n if (plan.length > request.limit) return yield* mismatch();\n\n const pages: Array<ReadPage> = [];\n let page: ReadPage | undefined;\n let pageBytes = 0;\n let previousSequence = request.fromSequenceExclusive;\n\n for (const row of plan) {\n if (row.sequence !== previousSequence + 1) return yield* mismatch();\n previousSequence = row.sequence;\n if (page === undefined || pageBytes + row.record_json_bytes > MAX_READ_PAGE_JSON_BYTES) {\n page = [row];\n pages.push(page);\n pageBytes = row.record_json_bytes;\n } else {\n page.push(row);\n pageBytes += row.record_json_bytes;\n }\n }\n\n const readPage = Effect.fn(\"DoJournal.readPage\")(function* (page: ReadPage) {\n const rows = yield* sql<Record<string, unknown>>`\n SELECT thread_id, sequence, record_id, batch_id, record_json\n FROM effect_agent_canonical_records\n WHERE thread_id = ${request.threadId}\n AND sequence >= ${page[0].sequence}\n AND sequence <= ${page[page.length - 1].sequence}\n ORDER BY sequence\n `.pipe(Effect.mapError(storageError(\"read canonical records\")));\n\n const decoded = yield* decodeRows(\n Schema.Array(RecordRow),\n \"effect_agent_canonical_records\",\n `${request.threadId}/${page[0].sequence}`,\n rows,\n );\n\n if (\n decoded.length !== page.length ||\n decoded.some(\n (row, index) =>\n row.thread_id !== request.threadId ||\n row.sequence !== page[index].sequence ||\n storedTextBytes(row.record_json) !== page[index].record_json_bytes,\n )\n ) {\n return yield* mismatch();\n }\n\n return decoded;\n });\n\n return {\n count: plan.length,\n records: Stream.fromIterable(pages).pipe(\n Stream.flatMap((page) => Stream.fromIterableEffect(readPage(page))),\n ),\n };\n });\n\n const exportThread = Effect.fn(\"DoJournal.exportThread\")(function* (threadId: string) {\n return yield* sql\n .withTransaction(\n Effect.gen(function* () {\n const threadRows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n created_at,\n tail_sequence,\n tail_digest,\n producer_epoch\n FROM effect_agent_threads\n WHERE thread_id = ${threadId}\n `.pipe(Effect.mapError(storageError(\"export thread\")));\n\n const thread = yield* decodeSingleRow(\n Schema.Array(ThreadRow),\n \"effect_agent_threads\",\n threadId,\n threadRows,\n );\n\n yield* failpoint(\"export:after-thread-read\");\n\n if (thread.tail_sequence > MAX_RECORDS_PER_THREAD)\n return yield* DoStorageError.make({\n operation: \"export thread\",\n message: \"The thread exceeds the current export record limit.\",\n });\n const records: Array<RecordRow> = [];\n let afterSequence = ZERO_SEQUENCE;\n\n while (afterSequence < thread.tail_sequence) {\n const limit = Math.min(1_024, thread.tail_sequence - afterSequence);\n\n const request = RawReadRequest.make({\n threadId,\n fromSequenceExclusive: afterSequence,\n limit,\n });\n\n const plan = yield* read(request);\n const page = yield* Stream.runCollect(plan.records);\n\n if (\n page.length !== limit ||\n page.some((record, index) => record.sequence !== afterSequence + index + 1)\n ) {\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_records\",\n rowKey: threadId,\n message:\n \"The exported canonical prefix is not contiguous through its captured tail.\",\n });\n }\n records.push(...page);\n afterSequence = page[page.length - 1].sequence;\n }\n\n const beyondTail =\n yield* sql`SELECT sequence FROM effect_agent_canonical_records WHERE thread_id=${threadId} AND sequence > ${thread.tail_sequence} LIMIT 1`.pipe(\n Effect.mapError(storageError(\"verify export tail\")),\n );\n\n if (beyondTail.length !== 0)\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_records\",\n rowKey: threadId,\n message: \"Canonical records exist beyond the captured thread tail.\",\n });\n\n return RawThreadExport.make({ thread, records });\n }),\n )\n .pipe(\n Effect.catchTag(\"SqlError\", (error) =>\n Effect.fail(storageError(\"export transaction\")(error)),\n ),\n );\n });\n\n const saveCheckpoint = Effect.fn(\"DoJournal.saveCheckpoint\")(function* (\n checkpoint: RawCheckpoint,\n ): Effect.fn.Return<void, CheckpointError> {\n if (checkpoint.threadId.length > MAX_IDENTIFIER_LENGTH) {\n return yield* DoStorageError.make({\n operation: \"save checkpoint\",\n message: \"Checkpoint identity exceeds the Durable Object storage bounds.\",\n });\n }\n yield* checkValueBound(\"save checkpoint\", checkpoint.checkpointJson);\n yield* withWriteTransaction(\"checkpoint transaction\")(\n Effect.gen(function* () {\n const threadRows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n created_at,\n tail_sequence,\n tail_digest,\n producer_epoch\n FROM effect_agent_threads\n WHERE thread_id = ${checkpoint.threadId}\n `.pipe(Effect.mapError(storageError(\"read checkpoint tail\")));\n\n const thread = yield* decodeSingleRow(\n Schema.Array(ThreadRow),\n \"effect_agent_threads\",\n checkpoint.threadId,\n threadRows,\n );\n\n if (checkpoint.throughSequence > thread.tail_sequence) {\n return yield* DoCheckpointConflict.make({\n message:\n `Checkpoint sequence ${checkpoint.throughSequence} is after canonical tail ` +\n `${thread.tail_sequence}.`,\n });\n }\n\n const checkpointRows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n through_sequence,\n tail_digest,\n checkpoint_json\n FROM effect_agent_checkpoints\n WHERE thread_id = ${checkpoint.threadId}\n AND through_sequence = ${checkpoint.throughSequence}\n `.pipe(Effect.mapError(storageError(\"read idempotent checkpoint\")));\n\n const existing = yield* decodeRows(\n Schema.Array(CheckpointRow),\n \"effect_agent_checkpoints\",\n `${checkpoint.threadId}/${checkpoint.throughSequence}`,\n checkpointRows,\n );\n\n if (existing.length > 1) {\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_checkpoints\",\n rowKey: `${checkpoint.threadId}/${checkpoint.throughSequence}`,\n message: \"A checkpoint primary key returned more than one row.\",\n });\n }\n if (existing.length === 1) {\n if (\n existing[0].tail_digest !== checkpoint.tailDigest ||\n existing[0].checkpoint_json !== checkpoint.checkpointJson\n ) {\n return yield* DoCheckpointConflict.make({\n message: \"A different checkpoint already exists at this canonical sequence.\",\n });\n }\n\n return;\n }\n\n yield* sql`\n INSERT INTO effect_agent_checkpoints (\n thread_id,\n through_sequence,\n tail_digest,\n checkpoint_json\n ) VALUES (\n ${checkpoint.threadId},\n ${checkpoint.throughSequence},\n ${checkpoint.tailDigest},\n ${checkpoint.checkpointJson}\n )\n `.pipe(Effect.mapError(storageError(\"insert checkpoint\")));\n }),\n );\n });\n\n const saveRecoveryCheckpoint = Effect.fn(\"DoJournal.saveRecoveryCheckpoint\")(function* (\n request: SaveRecoveryCheckpointRequest,\n checkpointJson: string,\n ) {\n const { checkpoint } = request;\n\n if (checkpoint.threadId.length > MAX_IDENTIFIER_LENGTH) {\n return yield* DoStorageError.make({\n operation: \"save recovery checkpoint\",\n message: \"Checkpoint identity exceeds the Durable Object storage bounds.\",\n });\n }\n yield* checkValueBound(\"save recovery checkpoint\", checkpointJson);\n // Keep injected waits outside the storage-backed transaction callback.\n yield* failpoint(\"save-recovery-checkpoint:before\");\n yield* withWriteTransaction(\"recovery checkpoint transaction\")(\n Effect.gen(function* () {\n const threads = yield* getThread(checkpoint.threadId);\n const thread = threads[0];\n\n if (thread === undefined)\n return yield* ThreadNotMaterialized.make({ threadId: checkpoint.threadId });\n if (request.producerEpoch !== thread.producer_epoch)\n return yield* FenceRejected.make({\n threadId: checkpoint.threadId,\n actualEpoch: thread.producer_epoch,\n attemptedEpoch: request.producerEpoch,\n });\n if (checkpoint.throughSequence > thread.tail_sequence)\n return yield* CheckpointRejected.make({\n threadId: checkpoint.threadId,\n reason: \"ahead-of-tail\",\n });\n\n const digests =\n checkpoint.throughSequence === 0\n ? [EMPTY_TAIL_DIGEST]\n : yield* getTailDigestAt(checkpoint.threadId, checkpoint.throughSequence);\n\n if (digests.length !== 1 || digests[0] !== checkpoint.tailDigest)\n return yield* CheckpointRejected.make({\n threadId: checkpoint.threadId,\n reason: \"digest-mismatch\",\n });\n\n yield* sql`\n INSERT INTO effect_agent_recovery_checkpoints (thread_id, through_sequence, tail_digest, checkpoint_json)\n VALUES (${checkpoint.threadId}, ${checkpoint.throughSequence}, ${checkpoint.tailDigest}, ${checkpointJson})\n ON CONFLICT (thread_id) DO UPDATE SET\n through_sequence = excluded.through_sequence,\n tail_digest = excluded.tail_digest,\n checkpoint_json = excluded.checkpoint_json\n WHERE excluded.through_sequence >= effect_agent_recovery_checkpoints.through_sequence\n `.pipe(Effect.mapError(storageError(\"save recovery checkpoint\")));\n }),\n );\n yield* failpoint(\"save-recovery-checkpoint:after\");\n });\n\n const loadRecoveryCheckpoint = Effect.fn(\"DoJournal.loadRecoveryCheckpoint\")(function* (\n threadId: string,\n ) {\n const rows = yield* sql<Record<string, unknown>>`\n SELECT thread_id, through_sequence, tail_digest, checkpoint_json\n FROM effect_agent_recovery_checkpoints\n WHERE thread_id = ${threadId}\n `.pipe(Effect.mapError(storageError(\"load recovery checkpoint\")));\n\n return yield* decodeRows(\n Schema.Array(CheckpointRow),\n \"effect_agent_recovery_checkpoints\",\n threadId,\n rows,\n );\n });\n\n const loadCheckpoint = Effect.fn(\"DoJournal.loadCheckpoint\")(function* (\n threadId: string,\n atOrBeforeSequence: CanonicalSequence,\n ) {\n const rows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n through_sequence,\n tail_digest,\n checkpoint_json\n FROM effect_agent_checkpoints\n WHERE thread_id = ${threadId}\n AND through_sequence <= ${atOrBeforeSequence}\n ORDER BY through_sequence DESC\n LIMIT 1\n `.pipe(Effect.mapError(storageError(\"load checkpoint\")));\n\n return yield* decodeRows(\n Schema.Array(CheckpointRow),\n \"effect_agent_checkpoints\",\n `${threadId}<=${atOrBeforeSequence}`,\n rows,\n );\n });\n\n const getTailDigestAt = Effect.fn(\"DoJournal.getTailDigestAt\")(function* (\n threadId: string,\n sequence: CanonicalSequence,\n ) {\n if (sequence === 0) {\n const threads = yield* getThread(threadId);\n\n return threads.length === 0\n ? []\n : [threads[0].tail_sequence === 0 ? threads[0].tail_digest : undefined].filter(\n (value): value is string => value !== undefined,\n );\n }\n\n const rows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n batch_id,\n first_sequence,\n last_sequence,\n batch_digest,\n tail_digest,\n batch_json\n FROM effect_agent_canonical_batches\n WHERE thread_id = ${threadId}\n AND last_sequence = ${sequence}\n `.pipe(Effect.mapError(storageError(\"read canonical digest at sequence\")));\n\n const batches = yield* decodeRows(\n Schema.Array(BatchRow),\n \"effect_agent_canonical_batches\",\n `${threadId}/${sequence}`,\n rows,\n );\n\n return batches.map((batch) => batch.tail_digest);\n });\n\n const scanStoredPayloads = Effect.fn(\"DoJournal.scanStoredPayloads\")(function* () {\n return yield* sql\n .withTransaction(\n Effect.gen(function* () {\n const threads = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n created_at,\n tail_sequence,\n tail_digest,\n producer_epoch\n FROM effect_agent_threads\n ORDER BY thread_id\n `.pipe(Effect.mapError(storageError(\"scan threads\")));\n\n const batches = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n batch_id,\n first_sequence,\n last_sequence,\n batch_digest,\n tail_digest,\n batch_json\n FROM effect_agent_canonical_batches\n ORDER BY thread_id, first_sequence\n `.pipe(Effect.mapError(storageError(\"scan canonical batches\")));\n\n const records = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n sequence,\n record_id,\n batch_id,\n record_json\n FROM effect_agent_canonical_records\n ORDER BY thread_id, sequence\n `.pipe(Effect.mapError(storageError(\"scan canonical records\")));\n\n const checkpoints = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n through_sequence,\n tail_digest,\n checkpoint_json\n FROM effect_agent_checkpoints\n ORDER BY thread_id, through_sequence\n `.pipe(Effect.mapError(storageError(\"scan checkpoints\")));\n\n return {\n threads: yield* decodeRows(\n Schema.Array(ThreadRow),\n \"effect_agent_threads\",\n \"startup_scan\",\n threads,\n ),\n batches: yield* decodeRows(\n Schema.Array(BatchRow),\n \"effect_agent_canonical_batches\",\n \"startup_scan\",\n batches,\n ),\n records: yield* decodeRows(\n Schema.Array(RecordRow),\n \"effect_agent_canonical_records\",\n \"startup_scan\",\n records,\n ),\n checkpoints: yield* decodeRows(\n Schema.Array(CheckpointRow),\n \"effect_agent_checkpoints\",\n \"startup_scan\",\n checkpoints,\n ),\n };\n }),\n )\n .pipe(\n Effect.catchTag(\"SqlError\", (error) =>\n Effect.fail(storageError(\"startup scan transaction\")(error)),\n ),\n );\n });\n\n return {\n append,\n checkValueBound,\n exportThread,\n getThread,\n getTailDigestAt,\n loadCheckpoint,\n loadRecoveryCheckpoint,\n saveRecoveryCheckpoint,\n materialize,\n read,\n saveCheckpoint,\n scanStoredPayloads,\n withWriteTransaction,\n } as const;\n};\n\nexport type DoJournal = ReturnType<typeof makeJournal>;\n\nexport const initializeDoJournal = ensureCurrentStorage;\n"],"mappings":"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A,SAAS,OAAO,KAAK;AACvB,CAAC,CACH,CACF,CACJ;;AAGA,MAAa,kBAAkB,OAAO,IAElC,QACA,OACA,QACA,SAEA,WAAW,QAAQ,OAAO,QAAQ,IAAI,CAAC,CAAC,KACtC,OAAO,SAAS,YACd,QAAQ,WAAW,IACf,OAAO,QAAQ,QAAQ,EAAE,IACzB,OAAO,KACL,yBAAyB,KAAK;CAC5B;CACA;CACA,SAAS,sCAAsC,QAAQ,OAAO;AAChE,CAAC,CACH,CACN,CACF,CACJ;;AAGA,MAAM,qBAAqB;CACzB,sBAAsB;EACpB;EACA;EACA;EACA;EACA;CACF;CACA,gCAAgC;EAC9B;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,gCAAgC;EAAC;EAAa;EAAY;EAAa;EAAY;CAAa;CAChG,0BAA0B;EAAC;EAAa;EAAoB;EAAe;CAAiB;CAC5F,0BAA0B;EACxB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,mCAAmC;EACjC;EACA;EACA;EACA;EACA;EACA;CACF;CACA,uBAAuB;EACrB;EACA;EACA;EACA;EACA;EACA;CACF;CACA,sCAAsC;EACpC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,4BAA4B;EAC1B;EACA;EACA;EACA;EACA;CACF;CACA,iCAAiC;EAC/B;EACA;EACA;EACA;EACA;EACA;CACF;CACA,kCAAkC;EAChC;EACA;EACA;EACA;EACA;EACA;CACF;CACA,iCAAiC;EAC/B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,mBAAmB,CAAC,OAAO,OAAO;CAClC,gCAAgC;EAC9B;EACA;EACA;EACA;CACF;AACF;AAEA,MAAM,yBAAyB,OAAO,GAAG,kCAAkC,CAAC,CAAC,WAC3E,SACA;CACA,MAAM,MAAM,OAAO,UAAU;CAsB7B,MAAM,kBAAkB;EACtB,GApBA,YAAY,IACR,qBACA;GACE,GAAG;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"}