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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/DoMemoryStore.mjs +1 -1
  2. package/dist/DoMessageDeliveryStore.mjs +1 -1
  3. package/dist/DoStorageFailpoint.d.mts +3 -1
  4. package/dist/DoStorageFailpoint.mjs +7 -2
  5. package/dist/DoStorageFailpoint.mjs.map +1 -1
  6. package/dist/DoStorageFailpointTesting.mjs +1 -4
  7. package/dist/DoStorageFailpointTesting.mjs.map +1 -1
  8. package/dist/{DoStorageVersion-NKnQU3eR.d.mts → DoStorageVersion-Mc7CXMdN.d.mts} +2 -2
  9. package/dist/DoStorageVersion.d.mts +1 -1
  10. package/dist/DoStorageVersion.mjs +2 -2
  11. package/dist/DoSubmissionLedger.mjs +121 -67
  12. package/dist/DoSubmissionLedger.mjs.map +1 -1
  13. package/dist/DoSubscriptionStore.mjs.map +1 -1
  14. package/dist/{DoThreadStore-CtyahRTW.mjs → DoThreadStore-CgIZQUNR.mjs} +30 -25
  15. package/dist/DoThreadStore-CgIZQUNR.mjs.map +1 -0
  16. package/dist/DoThreadStore.mjs +1 -1
  17. package/dist/PortProtocol.d.mts +12 -0
  18. package/dist/PortRouting.mjs +6 -1
  19. package/dist/PortRouting.mjs.map +1 -1
  20. package/dist/{do-journal-_MdLGTd3.mjs → do-journal-7P3DUBz0.mjs} +140 -65
  21. package/dist/do-journal-7P3DUBz0.mjs.map +1 -0
  22. package/dist/index.d.mts +1 -1
  23. package/dist/index.mjs +1 -1
  24. package/dist/{migrations-C3N9GN6A.mjs → migrations-CAO_akhD.mjs} +45 -22
  25. package/dist/migrations-CAO_akhD.mjs.map +1 -0
  26. package/dist/{owned-state-BHzUi0eb.mjs → owned-state-B4QhezMp.mjs} +8 -6
  27. package/dist/owned-state-B4QhezMp.mjs.map +1 -0
  28. package/package.json +1 -1
  29. package/src/DoStorageFailpoint.ts +4 -0
  30. package/src/DoStorageFailpointTesting.ts +9 -7
  31. package/src/DoSubmissionLedger.ts +271 -150
  32. package/src/DoSubscriptionStore.ts +1 -0
  33. package/src/DoThreadStore.ts +27 -50
  34. package/src/PortRouting.ts +10 -2
  35. package/src/internal/canonical-append.ts +1 -1
  36. package/src/internal/do-journal.ts +987 -800
  37. package/src/internal/migrations.ts +53 -10
  38. package/src/internal/owned-state.ts +18 -7
  39. package/src/internal/prompt-checkpoint.ts +19 -13
  40. package/src/internal/storage-span.ts +22 -13
  41. package/dist/DoThreadStore-CtyahRTW.mjs.map +0 -1
  42. package/dist/do-journal-_MdLGTd3.mjs.map +0 -1
  43. package/dist/migrations-C3N9GN6A.mjs.map +0 -1
  44. package/dist/owned-state-BHzUi0eb.mjs.map +0 -1
@@ -6,7 +6,8 @@ import {
6
6
  import { createSqlThreadWorkTables } from "@yielded/agent-storage-sql/sql-thread-work";
7
7
  import { makeSqliteLayoutInspection } from "@yielded/agent-storage-sql/sqlite-layout-inspection";
8
8
  import { CURRENT_RECORD_FORMAT } from "@yielded/agent/records";
9
- import { Effect, Schema } from "effect";
9
+ import { SqlStorageOwner } from "@yielded/agent/sql-memory-store";
10
+ import { Effect, Option, Schema } from "effect";
10
11
  import * as SqlClient from "effect/sql/SqlClient";
11
12
  import type { SqlError } from "effect/sql/SqlError";
12
13
 
@@ -16,7 +17,7 @@ import {
16
17
  DoStorageError,
17
18
  } from "../DoStorageError.ts";
18
19
 
19
- export const CurrentDoStorageVersion = 27;
20
+ export const CurrentDoStorageVersion = 28;
20
21
 
21
22
  /** Fresh layout only. Unsupported stores are rejected before these statements execute. */
22
23
  const layoutStatements = [
@@ -70,7 +71,6 @@ const layoutStatements = [
70
71
  "CREATE TABLE effect_agent_archive_batches (thread_id TEXT NOT NULL, batch_id TEXT NOT NULL, range_first_sequence INTEGER NOT NULL, batch_json TEXT NOT NULL, PRIMARY KEY (thread_id, batch_id), FOREIGN KEY (thread_id, batch_id) REFERENCES effect_agent_canonical_batches(thread_id, batch_id) ON DELETE RESTRICT, CONSTRAINT effect_agent_archive_batches_range_fkey FOREIGN KEY (thread_id, range_first_sequence) REFERENCES effect_agent_journal_ranges(thread_id, first_sequence) ON DELETE RESTRICT)",
71
72
  "CREATE TABLE effect_agent_archive_records (thread_id TEXT NOT NULL, sequence INTEGER NOT NULL, range_first_sequence INTEGER NOT NULL, record_json TEXT NOT NULL, PRIMARY KEY (thread_id, sequence), FOREIGN KEY (thread_id, sequence) REFERENCES effect_agent_canonical_records(thread_id, sequence) ON DELETE RESTRICT, CONSTRAINT effect_agent_archive_records_range_fkey FOREIGN KEY (thread_id, range_first_sequence) REFERENCES effect_agent_journal_ranges(thread_id, first_sequence) ON DELETE RESTRICT)",
72
73
  "CREATE UNIQUE INDEX effect_agent_canonical_batches_sequence ON effect_agent_canonical_batches(thread_id, first_sequence)",
73
- "CREATE INDEX effect_agent_canonical_batches_last ON effect_agent_canonical_batches(thread_id, last_sequence)",
74
74
  "CREATE TABLE effect_agent_live_child_reservations (reservation_id TEXT PRIMARY KEY NOT NULL, thread_id TEXT NOT NULL)",
75
75
  "CREATE INDEX effect_agent_live_child_reservations_thread ON effect_agent_live_child_reservations(thread_id, reservation_id)",
76
76
  // Compact native positions keep accepted identities out of bounded export cursors.
@@ -91,6 +91,7 @@ const layoutObjects = (statements: ReadonlyArray<string>) =>
91
91
  statements.map((statement, index) => {
92
92
  const name = /^CREATE (TABLE|(?:UNIQUE )?INDEX|TRIGGER) "?([a-z_][a-z_0-9]*)"?/.exec(statement);
93
93
 
94
+ // oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- The synchronous SQL layout parser rejects malformed developer-authored declarations before storage mutation.
94
95
  if (name === null) throw new Error("Invalid fresh layout statement");
95
96
 
96
97
  return [name[1].replace("UNIQUE ", "").toLowerCase(), name[2], index] as const;
@@ -140,10 +141,15 @@ const inspection = (version: number, statements: ReadonlyArray<string>) =>
140
141
  // Released predecessors retain the same record format and canonical tables.
141
142
  const addedIndexes = new Set(["effect_agent_message_deliveries_peer_retained"]);
142
143
 
143
- const layout25Statements = layoutObjects(layoutStatements)
144
+ const layout27Statements = [
145
+ ...layoutStatements,
146
+ "CREATE INDEX effect_agent_canonical_batches_last ON effect_agent_canonical_batches(thread_id, last_sequence)",
147
+ ];
148
+
149
+ const layout25Statements = layoutObjects(layout27Statements)
144
150
  .filter(([, name]) => !addedIndexes.has(name))
145
151
  .map(([, , index]) =>
146
- layoutStatements[index]
152
+ layout27Statements[index]
147
153
  .replace(", peer_retained_until_millis INTEGER", "")
148
154
  .replace(
149
155
  "'$.envelope.messageAdmission.peerName') IS NOT NULL",
@@ -153,7 +159,8 @@ const layout25Statements = layoutObjects(layoutStatements)
153
159
 
154
160
  const { decode, readObjects, readHeader } = inspection(CurrentDoStorageVersion, layoutStatements);
155
161
  const layout25 = inspection(25, layout25Statements);
156
- const layout26 = inspection(26, layoutStatements);
162
+ const layout26 = inspection(26, layout27Statements);
163
+ const layout27 = inspection(27, layout27Statements);
157
164
 
158
165
  const inspectStorage = Effect.fnUntraced(function* (
159
166
  allowUpgrade = false,
@@ -184,10 +191,10 @@ const inspectStorage = Effect.fnUntraced(function* (
184
191
 
185
192
  const version = legacy.value;
186
193
 
187
- if (allowUpgrade && (version === 25 || version === 26)) {
194
+ if (allowUpgrade && (version === 25 || version === 26 || version === 27)) {
188
195
  if (version === 25 && objects.some(({ name }) => addedIndexes.has(name)))
189
196
  return yield* incompatible(version, "Mixed layout 25 and 26 objects.");
190
- const predecessor = version === 25 ? layout25 : layout26;
197
+ const predecessor = version === 25 ? layout25 : version === 26 ? layout26 : layout27;
191
198
  const header = yield* predecessor.readHeader(objects, version);
192
199
 
193
200
  yield* predecessor.readManagedTriggers(true);
@@ -208,8 +215,8 @@ export const readDoStorageHeader = Effect.fnUntraced(function* () {
208
215
  return header;
209
216
  });
210
217
 
211
- /** Initialize fresh storage or atomically upgrade the exact released layouts 25 and 26. */
212
- export const ensureDoStorageLayout = Effect.fn("DoStorage.initializeLayout")(function* () {
218
+ /** Initialize fresh storage or atomically upgrade the exact released layouts 25–27. */
219
+ const initializeDoStorageLayout = Effect.fn("DoStorage.initializeLayout")(function* () {
213
220
  const sql = (yield* SqlClient.SqlClient).withoutTransforms();
214
221
 
215
222
  return yield* sql
@@ -243,6 +250,9 @@ export const ensureDoStorageLayout = Effect.fn("DoStorage.initializeLayout")(fun
243
250
  }),
244
251
  ),
245
252
  );
253
+ }
254
+ if (header !== undefined && header.layoutVersion < CurrentDoStorageVersion) {
255
+ yield* sql`DROP INDEX effect_agent_canonical_batches_last`;
246
256
  yield* sql`UPDATE effect_agent_schema SET layout_version=${CurrentDoStorageVersion} WHERE singleton=1`;
247
257
  yield* sql`UPDATE effect_agent_meta SET value=${String(CurrentDoStorageVersion)} WHERE key='storage_version'`;
248
258
 
@@ -268,3 +278,36 @@ export const ensureDoStorageLayout = Effect.fn("DoStorage.initializeLayout")(fun
268
278
  )
269
279
  .pipe(Effect.catchTag("SqlError", storageError));
270
280
  });
281
+
282
+ const initializedLayouts = new WeakMap<object, DoStorageHeader>();
283
+
284
+ /** Share committed inspection within one live Object owner; maintenance invalidates it. */
285
+ export const ensureDoStorageLayout = Effect.fnUntraced(function* () {
286
+ const sql = yield* SqlClient.SqlClient;
287
+ const owner = yield* SqlStorageOwner;
288
+
289
+ // A caller-owned transaction can still roll back after this initializer returns.
290
+ if (owner === undefined || Option.isSome(yield* Effect.serviceOption(sql.transactionService)))
291
+ return yield* initializeDoStorageLayout();
292
+
293
+ const identity = owner.identity ?? owner;
294
+
295
+ return yield* owner.read(
296
+ Effect.gen(function* () {
297
+ const previous = initializedLayouts.get(identity);
298
+
299
+ if (previous !== undefined) return previous;
300
+ const header = yield* initializeDoStorageLayout();
301
+
302
+ const invalidate = () => {
303
+ initializedLayouts.delete(identity);
304
+ owner.invalidators.delete(invalidate);
305
+ };
306
+
307
+ initializedLayouts.set(identity, header);
308
+ owner.invalidators.add(invalidate);
309
+
310
+ return header;
311
+ }),
312
+ );
313
+ });
@@ -195,16 +195,19 @@ export const ownedRows = <A, I>(
195
195
  maxRows = Infinity,
196
196
  ) =>
197
197
  state.read(
198
- Effect.gen(function* () {
198
+ Effect.suspend(() => {
199
199
  const view = current.get(id);
200
200
 
201
- if (view !== undefined) return view.rows;
202
-
203
- const rows = yield* decode(yield* query);
201
+ if (view !== undefined) return Effect.succeed(view.rows);
204
202
 
205
- retain(id, matches, rows, maxRows);
203
+ return query.pipe(
204
+ Effect.flatMap(decode),
205
+ Effect.map((rows) => {
206
+ retain(id, matches, rows, maxRows);
206
207
 
207
- return rows;
208
+ return rows;
209
+ }),
210
+ );
208
211
  }),
209
212
  );
210
213
 
@@ -274,6 +277,14 @@ export const ownedRows = <A, I>(
274
277
  return rows;
275
278
  });
276
279
 
277
- return { by, byFields, matching, seed, write: apply(false), remove: apply(true) };
280
+ return {
281
+ by,
282
+ byFields,
283
+ matching,
284
+ seed,
285
+ seedMatching: retain,
286
+ write: apply(false),
287
+ remove: apply(true),
288
+ };
278
289
  };
279
290
  };
@@ -40,7 +40,8 @@ const keyFor = (prefix: string, chunk: number) => prefix + String(chunk).padStar
40
40
  /**
41
41
  * Versioned derivative keys use the adapter's existing metadata store. Canonical layout and
42
42
  * export are unchanged. Chunking keeps SQL values below the DO limit; loading is one bounded
43
- * query followed by one parse of the native prompt. Only the latest checkpoint is retained.
43
+ * query followed by one parse of the native prompt. Retain unchanged chunks when replacing
44
+ * the checkpoint, so append-only growth writes at most the old tail and new chunks.
44
45
  */
45
46
  export const makePromptCheckpoints = (
46
47
  sql: SqlClient,
@@ -107,8 +108,8 @@ export const makePromptCheckpoints = (
107
108
  }),
108
109
  )
109
110
  .pipe(Effect.orElseSucceed(() => Option.none())),
110
- save: (input) =>
111
- Effect.gen(function* () {
111
+ save: Effect.fnUntraced(
112
+ function* (input) {
112
113
  const checkpoint = yield* decodeWrite(input);
113
114
 
114
115
  if (
@@ -140,19 +141,24 @@ export const makePromptCheckpoints = (
140
141
  const [head] = yield* journal.getThread(checkpoint.threadId);
141
142
 
142
143
  if (head === undefined || head.tail_sequence !== checkpoint.throughSequence) return;
143
- yield* sql`DELETE FROM effect_agent_meta WHERE key >= ${prefix} AND key < ${prefix + "~"}`;
144
+ yield* sql`DELETE FROM effect_agent_meta WHERE key >= ${keyFor(prefix, chunks.length + 1)} AND key < ${prefix + "~"}`;
144
145
  for (const [index, value] of [header, ...chunks].entries())
145
- yield* sql`INSERT INTO effect_agent_meta (key, value) VALUES (${keyFor(prefix, index)}, ${value})`;
146
+ yield* sql`INSERT INTO effect_agent_meta (key, value) VALUES (${keyFor(prefix, index)}, ${value})
147
+ ON CONFLICT (key) DO UPDATE SET value = excluded.value
148
+ WHERE effect_agent_meta.value <> excluded.value`;
146
149
  }),
147
150
  )
148
151
  .pipe(Effect.provideService(SqlClient, sql));
149
- }).pipe(
150
- Effect.mapError((cause) =>
151
- ThreadStoreError.make({
152
- operation: "save prompt checkpoint",
153
- message: "Unable to retain a disposable prompt checkpoint",
154
- cause,
155
- }),
152
+ },
153
+ (effect) =>
154
+ effect.pipe(
155
+ Effect.mapError((cause) =>
156
+ ThreadStoreError.make({
157
+ operation: "save prompt checkpoint",
158
+ message: "Unable to retain a disposable prompt checkpoint",
159
+ cause,
160
+ }),
161
+ ),
156
162
  ),
157
- ),
163
+ ),
158
164
  });
@@ -1,4 +1,4 @@
1
- import { Effect, Predicate, Result } from "effect";
1
+ import { Effect, Predicate, References, Result, Tracer } from "effect";
2
2
 
3
3
  type Tagged = { readonly _tag: string; readonly reason?: unknown };
4
4
 
@@ -26,16 +26,25 @@ export const annotateStorageError = (error: Tagged) =>
26
26
  : {}),
27
27
  });
28
28
 
29
- export const withStorageSpan =
30
- (name: string, expected: (error: Tagged) => boolean = () => false) =>
31
- <A, E extends Tagged, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>
32
- storageResult(effect, expected).pipe(
33
- Effect.tap((result) =>
34
- Result.isFailure(result)
35
- ? Effect.annotateCurrentSpan({ "storage.outcome": result.failure._tag })
36
- : Effect.void,
37
- ),
38
- Effect.tapError(annotateStorageError),
39
- Effect.withSpan(name),
40
- Effect.flatMap(Effect.fromResult),
29
+ export const withStorageSpan = (
30
+ name: string,
31
+ expected: (error: Tagged) => boolean = () => false,
32
+ ) => {
33
+ const span = Effect.withSpan(name);
34
+
35
+ return <A, E extends Tagged, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>
36
+ Effect.withFiber((fiber) =>
37
+ !fiber.getRef(References.TracerEnabled) || fiber.getRef(Tracer.Tracer) === Tracer.nativeTracer
38
+ ? effect
39
+ : storageResult(effect, expected).pipe(
40
+ Effect.tap((result) =>
41
+ Result.isFailure(result)
42
+ ? Effect.annotateCurrentSpan({ "storage.outcome": result.failure._tag })
43
+ : Effect.void,
44
+ ),
45
+ Effect.tapError(annotateStorageError),
46
+ span,
47
+ Effect.flatMap(Effect.fromResult),
48
+ ),
41
49
  );
50
+ };
@@ -1 +0,0 @@
1
- {"version":3,"file":"DoThreadStore-CtyahRTW.mjs","names":[],"sources":["../src/internal/canonical-append.ts","../src/internal/prompt-checkpoint.ts","../src/DoThreadStore.ts"],"sourcesContent":["import { prepareSqlAppend } from \"@yielded/agent-storage-sql/sql-thread-store\";\nimport type { AppendRequest } from \"@yielded/agent/thread-store\";\nimport { PreparedAppend } from \"@yielded/agent/thread-store\";\nimport { Effect } from \"effect\";\n\nexport const DO_OFFSET_PREFIX = \"effect-agent-do@1:\";\n\n/** Prepare the publisher's privately captured canonical request before the writer. */\nexport const prepareCanonicalAppend = Effect.fnUntraced(function* (input: AppendRequest) {\n const request = yield* PreparedAppend.capture(input);\n\n const raw = yield* prepareSqlAppend(request, DO_OFFSET_PREFIX);\n\n return { request, raw };\n});\n","import { utf8ByteLength } from \"@yielded/agent/digest\";\nimport {\n MAX_PROMPT_CHECKPOINT_BYTES,\n PromptCheckpoint,\n PromptCheckpointHead,\n PromptCheckpointRead,\n ThreadStoreError,\n type PromptCheckpoints,\n} from \"@yielded/agent/thread-store\";\nimport { Effect, Option, Schema } from \"effect\";\nimport { SqlClient } from \"effect/sql/SqlClient\";\n\nimport type { DoJournal } from \"./do-journal.ts\";\n\nconst Header = Schema.Struct({\n ...PromptCheckpointHead.fields,\n chunks: Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: 64 })),\n});\n\nconst decodeHeader = Schema.decodeEffect(Schema.fromJsonString(Header));\nconst encodeHeader = Schema.encodeEffect(Schema.fromJsonString(Header));\n\nconst decodeRows = Schema.decodeUnknownEffect(\n Schema.Array(\n Schema.Struct({\n key: Schema.String,\n value: Schema.String.check(Schema.isMaxLength(2_000_000)),\n }),\n ).check(Schema.isMaxLength(65)),\n);\n\nconst decodeWrite = Schema.decodeEffect(PromptCheckpoint);\nconst decodeRead = Schema.decodeEffect(PromptCheckpointRead);\n\nexport const promptCheckpointPrefix = (threadId: string) =>\n `prompt-checkpoint/${JSON.stringify(threadId)}/`;\n\nconst keyFor = (prefix: string, chunk: number) => prefix + String(chunk).padStart(5, \"0\");\n\n/**\n * Versioned derivative keys use the adapter's existing metadata store. Canonical layout and\n * export are unchanged. Chunking keeps SQL values below the DO limit; loading is one bounded\n * query followed by one parse of the native prompt. Only the latest checkpoint is retained.\n */\nexport const makePromptCheckpoints = (\n sql: SqlClient,\n journal: DoJournal,\n maxValueBytes: number,\n): PromptCheckpoints => ({\n load: (input) =>\n journal.state\n .read(\n Effect.gen(function* () {\n const request = yield* decodeRead(input);\n const prefix = promptCheckpointPrefix(request.threadId);\n\n // Every row repeats the Thread ID. Bound those known key bytes separately from\n // the prompt and header so supported long IDs do not consume the prompt allowance.\n const maxHydratedBytes =\n MAX_PROMPT_CHECKPOINT_BYTES + 16_384 + 65 * utf8ByteLength(keyFor(prefix, 0));\n\n const rows = yield* decodeRows(\n yield* sql`\n SELECT key, value FROM effect_agent_meta\n WHERE key >= ${prefix} AND key < ${prefix + \"~\"}\n AND (SELECT sum(length(CAST(key AS BLOB)) + length(CAST(value AS BLOB)))\n FROM effect_agent_meta\n WHERE key >= ${prefix} AND key < ${prefix + \"~\"})\n <= ${maxHydratedBytes}\n ORDER BY key LIMIT 66`,\n );\n\n const first = rows[0];\n\n if (first === undefined || first.key !== keyFor(prefix, 0)) return Option.none();\n const header = yield* decodeHeader(first.value);\n\n if (\n header.threadId !== request.threadId ||\n header.historyThrough >= header.throughSequence ||\n header.chunks !== rows.length - 1 ||\n rows.some((row, index) => row.key !== keyFor(prefix, index))\n )\n return Option.none();\n const [head] = yield* journal.getThread(request.threadId);\n\n if (\n head === undefined ||\n head.tail_sequence !== request.throughSequence ||\n head.tail_sequence < header.throughSequence\n )\n return Option.none();\n let bytes = 0;\n\n for (const row of rows) {\n bytes += utf8ByteLength(row.value);\n if (bytes > MAX_PROMPT_CHECKPOINT_BYTES + 16_384) return Option.none();\n }\n\n return Option.some({\n ...header,\n promptJson: rows\n .slice(1)\n .map((row) => row.value)\n .join(\"\"),\n });\n }),\n )\n .pipe(Effect.orElseSucceed(() => Option.none())),\n save: (input) =>\n Effect.gen(function* () {\n const checkpoint = yield* decodeWrite(input);\n\n if (\n utf8ByteLength(checkpoint.promptJson) > MAX_PROMPT_CHECKPOINT_BYTES ||\n checkpoint.historyThrough >= checkpoint.throughSequence\n )\n return;\n const prefix = promptCheckpointPrefix(checkpoint.threadId);\n const chunks: Array<string> = [];\n // Three UTF-8 bytes per UTF-16 code unit is a conservative bound. Keep surrogate pairs\n // together so SQLite never normalizes an isolated half while persisting a chunk.\n const chars = Math.floor(Math.min(maxValueBytes - 4_096, 1_000_000) / 3);\n\n if (chars < 1) return;\n for (let offset = 0; offset < checkpoint.promptJson.length;) {\n let end = Math.min(offset + chars, checkpoint.promptJson.length);\n const last = checkpoint.promptJson.charCodeAt(end - 1);\n\n if (last >= 0xd800 && last <= 0xdbff) end--;\n if (end <= offset || chunks.length >= 64) return;\n chunks.push(checkpoint.promptJson.slice(offset, end));\n offset = end;\n }\n const header = yield* encodeHeader({ ...checkpoint, chunks: chunks.length });\n\n yield* journal.state\n .transaction(\n Effect.gen(function* () {\n const [head] = yield* journal.getThread(checkpoint.threadId);\n\n if (head === undefined || head.tail_sequence !== checkpoint.throughSequence) return;\n yield* sql`DELETE FROM effect_agent_meta WHERE key >= ${prefix} AND key < ${prefix + \"~\"}`;\n for (const [index, value] of [header, ...chunks].entries())\n yield* sql`INSERT INTO effect_agent_meta (key, value) VALUES (${keyFor(prefix, index)}, ${value})`;\n }),\n )\n .pipe(Effect.provideService(SqlClient, sql));\n }).pipe(\n Effect.mapError((cause) =>\n ThreadStoreError.make({\n operation: \"save prompt checkpoint\",\n message: \"Unable to retain a disposable prompt checkpoint\",\n cause,\n }),\n ),\n ),\n});\n","import { BrowserCrypto } from \"@effect/platform-browser\";\nimport { SqliteClient } from \"@effect/sql-sqlite-do\";\nimport { makeSqlThreadImport } from \"@yielded/agent-storage-sql/sql-thread-import\";\nimport {\n makeSelectedReads,\n SelectedReadOwner,\n} from \"@yielded/agent-storage-sql/sql-thread-native-reads\";\nimport { decodeExportRecordJson } from \"@yielded/agent/record-format\";\nimport {\n CanonicalRecordEnvelope,\n CanonicalSequence,\n ObservationOffset,\n} from \"@yielded/agent/records\";\nimport { StorageOwner } from \"@yielded/agent/run-storage\";\nimport { SqlStorageOwner } from \"@yielded/agent/sql-memory-store\";\nimport { MAX_ARCHIVE_RANGE_PAGE } from \"@yielded/agent/thread-archive-range\";\nimport { ThreadImport } from \"@yielded/agent/thread-import\";\nimport {\n type ThreadExportRequest,\n AppendConflict,\n AppendResult,\n CheckpointRejected,\n ThreadCheckpoint,\n ThreadMaterialization,\n ThreadNotMaterialized,\n ThreadObservation,\n ThreadReadRequest,\n ThreadStore,\n ThreadReader,\n type ThreadCheckpoints,\n ThreadStoreError,\n ThreadStoreDiagnostic,\n ThreadTail,\n ThreadTailRequest,\n type AppendRequest,\n PreparedAppend,\n LoadCheckpointRequest,\n SaveCheckpointRequest,\n} from \"@yielded/agent/thread-store\";\nimport { checkExportSource } from \"@yielded/agent/thread-transfer\";\nimport { Clock, Context, Crypto, Effect, Layer, Option, Ref, Schema, Stream } from \"effect\";\nimport * as SqlClientService from \"effect/sql/SqlClient\";\nimport { isSqlError } from \"effect/sql/SqlError\";\n\nimport {\n DEFAULT_MAX_STORED_VALUE_BYTES,\n DoStorageConfig,\n DoStorageConfigValue,\n} from \"./DoStorageConfig.ts\";\nimport {\n type DoStorageCompatibilityError,\n DoAppendConflict,\n DoCheckpointConflict,\n type DoStorageFailpointLocation,\n DoStorageCorruptionError,\n DoStorageError,\n} from \"./DoStorageError.ts\";\nimport { DoStorageFailpoint, type DoStorageFailpointHandler } from \"./DoStorageFailpoint.ts\";\nimport { DO_OFFSET_PREFIX, prepareCanonicalAppend } from \"./internal/canonical-append.ts\";\nimport {\n initializeDoJournal,\n RawCheckpoint,\n RawReadRequest,\n type DoJournal,\n} from \"./internal/do-journal.ts\";\nimport { readDoStorageHeader } from \"./internal/migrations.ts\";\nimport { invalidateOwnedState, ownedState } from \"./internal/owned-state.ts\";\nimport { makePromptCheckpoints, promptCheckpointPrefix } from \"./internal/prompt-checkpoint.ts\";\nimport { isAppendContention, withStorageSpan } from \"./internal/storage-span.ts\";\n\n/**\n * Convenience-layer construction options. `storage` is the Durable Object's own\n * `ctx.storage` handle, injected as a value (DEPLOY-010: platform bindings enter only\n * through Layers; this package never imports `cloudflare:workers`).\n */\nexport interface DoStorageOptions {\n readonly storage: DurableObjectStorage;\n readonly observationPollInterval?: number | undefined;\n /**\n * Maximum bytes for any single stored value; must stay under the platform's 2 MB\n * per-value limit. Defaults to `DEFAULT_MAX_STORED_VALUE_BYTES`.\n */\n readonly maxStoredValueBytes?: number | undefined;\n /**\n * Audit journal payloads, ownership, and batch coverage in bounded pages on open, including\n * orphan rows and rows outside declared ranges. Defaults to false. Full reads validate\n * canonical records; readPrompt trusts write-time validation of the omitted fields.\n */\n readonly verifyOnOpen?: boolean | undefined;\n readonly failpoint?: DoStorageFailpointHandler | undefined;\n}\n\nexport type DoStorageInitializationError =\n | DoStorageCompatibilityError\n | DoStorageCorruptionError\n | DoStorageError;\n\nconst OffsetText = Schema.String.check(Schema.isMaxLength(4 * 1024));\nconst ZERO_CANONICAL_SEQUENCE = Schema.decodeSync(CanonicalSequence)(0);\nconst isDoAppendConflict = Schema.is(DoAppendConflict);\nconst isDoCheckpointConflict = Schema.is(DoCheckpointConflict);\n// Reuse the same AST/parser across reads. Reconstructing a JSON codec per row\n// defeats Schema's parser cache and repeatedly walks the canonical union.\nconst ThreadCheckpointJson = Schema.fromJsonString(ThreadCheckpoint);\nconst decodeCanonicalRecord = decodeExportRecordJson;\n\nconst storeError = (\n operation: string,\n error: { readonly message: string; readonly diagnostic?: ThreadStoreDiagnostic },\n) =>\n ThreadStoreError.make({\n cause: error,\n operation,\n message: error.message,\n ...(error.diagnostic === undefined ? {} : { diagnostic: error.diagnostic }),\n });\n\nconst schemaStoreError = (operation: string, error: Schema.SchemaError) =>\n ThreadStoreError.make({\n operation,\n message: \"A Thread storage value does not satisfy its schema\",\n diagnostic: ThreadStoreDiagnostic.make({\n causeTag: error._tag,\n operation,\n issueTag: error.issue._tag,\n }),\n });\n\nconst makeOffset = (\n threadId: ThreadMaterialization[\"threadId\"],\n sequence: number,\n): Effect.Effect<ObservationOffset, ThreadStoreError> =>\n Schema.decodeEffect(CanonicalSequence)(sequence).pipe(\n Effect.flatMap((validatedSequence) =>\n Schema.decodeEffect(ObservationOffset)(\n `${DO_OFFSET_PREFIX}${encodeURIComponent(threadId)}:${validatedSequence}`,\n ),\n ),\n Effect.mapError((error) => schemaStoreError(\"encode observation offset\", error)),\n );\n\nconst parseOffset = Effect.fnUntraced(function* (\n threadId: ThreadMaterialization[\"threadId\"],\n offset: ObservationOffset | undefined,\n): Effect.fn.Return<CanonicalSequence, ThreadStoreError> {\n if (offset === undefined) return ZERO_CANONICAL_SEQUENCE;\n\n const text = yield* Schema.decodeEffect(OffsetText)(offset).pipe(\n Effect.mapError((error) => schemaStoreError(\"decode observation offset\", error)),\n );\n\n const threadPrefix = `${DO_OFFSET_PREFIX}${encodeURIComponent(threadId)}:`;\n\n if (!text.startsWith(threadPrefix)) {\n return yield* ThreadStoreError.make({\n operation: \"decode observation offset\",\n message: \"The observation offset belongs to a different adapter, storage version, or Thread.\",\n });\n }\n const sequenceText = text.slice(threadPrefix.length);\n\n if (!/^(0|[1-9][0-9]*)$/.test(sequenceText)) {\n return yield* ThreadStoreError.make({\n operation: \"decode observation offset\",\n message: \"The observation offset is malformed.\",\n });\n }\n\n return yield* Schema.decodeEffect(CanonicalSequence)(Number(sequenceText)).pipe(\n Effect.mapError((error) => schemaStoreError(\"decode observation offset\", error)),\n );\n});\n\nconst encodeCheckpoint = (checkpoint: ThreadCheckpoint): Effect.Effect<string, ThreadStoreError> =>\n Schema.encodeEffect(ThreadCheckpointJson)(checkpoint).pipe(\n Effect.mapError((error) => schemaStoreError(\"encode checkpoint\", error)),\n );\n\nconst envelopes = new WeakMap<object, CanonicalRecordEnvelope>();\n\nconst decodeEnvelope = Effect.fnUntraced(function* (row: {\n readonly batch_id: string;\n readonly thread_id: string;\n readonly record_json: string;\n readonly sequence: CanonicalSequence;\n}) {\n const cached = envelopes.get(row);\n\n if (cached !== undefined) return cached;\n\n const record = yield* decodeCanonicalRecord(row.record_json).pipe(\n Effect.mapError((error) =>\n ThreadStoreError.make({\n operation: \"decode canonical record\",\n message: \"The canonical record does not satisfy its schema\",\n diagnostic: ThreadStoreDiagnostic.make({\n causeTag: error._tag,\n operation: \"decode canonical record\",\n decoder: \"CanonicalRecord\",\n sequence: row.sequence,\n issueTag: error.issue._tag,\n }),\n }),\n ),\n Effect.tapError((error) =>\n Effect.annotateCurrentSpan({\n \"storage.failure.operation\": error.diagnostic?.operation,\n \"storage.failure.cause\": error.diagnostic?.causeTag,\n \"storage.failure.decoder\": error.diagnostic?.decoder,\n \"storage.failure.sequence\": row.sequence,\n \"storage.failure.issue\": error.diagnostic?.issueTag,\n }),\n ),\n );\n\n const threadId = yield* Schema.decodeEffect(CanonicalRecordEnvelope.fields.threadId)(\n row.thread_id,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"decode thread identity\", error)));\n\n const offset = yield* makeOffset(threadId, row.sequence);\n\n const batchId = yield* Schema.decodeEffect(CanonicalRecordEnvelope.fields.batchId)(\n row.batch_id,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"decode batch identity\", error)));\n\n const envelope = new CanonicalRecordEnvelope(\n { threadId, batchId, sequence: row.sequence, offset, record },\n { disableChecks: true },\n );\n\n envelopes.set(row, envelope);\n\n return envelope;\n});\n\nconst decodeCheckpoint = (\n checkpointJson: string,\n): Effect.Effect<ThreadCheckpoint, ThreadStoreError> =>\n Schema.decodeEffect(Schema.fromJsonString(ThreadCheckpoint))(checkpointJson).pipe(\n Effect.mapError((error) => schemaStoreError(\"decode checkpoint\", error)),\n );\n\nconst requireThread = Effect.fnUntraced(function* (\n journal: DoJournal,\n threadId: ThreadMaterialization[\"threadId\"],\n) {\n const rows = yield* journal\n .getThread(threadId)\n .pipe(Effect.mapError((error) => storeError(\"read thread\", error)));\n\n if (rows.length === 0) {\n return yield* ThreadNotMaterialized.make({ threadId });\n }\n\n return rows[0];\n});\n\nconst requireBatchBoundary = Effect.fnUntraced(function* (\n journal: DoJournal,\n threadId: ThreadMaterialization[\"threadId\"],\n sequence: CanonicalSequence,\n) {\n const valid = yield* journal\n .isBatchBoundary(threadId, sequence)\n .pipe(Effect.mapError((error) => storeError(\"read checkpoint boundary\", error)));\n\n if (!valid) {\n return yield* CheckpointRejected.make({\n threadId,\n reason: \"not-batch-boundary\",\n });\n }\n});\n\n/** Audit excluded rows before paging owners and bounded ranges; never collect Thread payloads. */\nconst decodeStartupPayloads = Effect.fnUntraced(function* (journal: DoJournal) {\n yield* journal.archiveRanges.verifyCoverage;\n let afterThreadId: string | undefined;\n\n while (true) {\n const owners = yield* journal.archiveRanges.threadPage(afterThreadId);\n\n for (const owner of owners) {\n yield* journal.archiveRanges.verifyThread(owner.thread_id);\n afterThreadId = owner.thread_id;\n }\n if (owners.length < MAX_ARCHIVE_RANGE_PAGE) break;\n }\n});\n\nconst makeServices = Effect.fnUntraced(function* () {\n const config = yield* DoStorageConfig;\n const failpoint = yield* DoStorageFailpoint;\n const sql = yield* SqlClientService.SqlClient;\n const crypto = yield* Crypto.Crypto;\n const journal = yield* initializeDoJournal(sql, failpoint.hit, config.maxStoredValueBytes);\n\n if (config.verifyOnOpen) {\n yield* journal.state.read(decodeStartupPayloads(journal)).pipe(\n Effect.mapError((cause) =>\n DoStorageCorruptionError.make({\n table: \"effect_agent_journal_ranges\",\n rowKey: \"verification\",\n message: cause.message,\n }),\n ),\n );\n }\n\n const hitFailpoint = (\n location: DoStorageFailpointLocation,\n ): Effect.Effect<void, ThreadStoreError> =>\n failpoint\n .hit(location)\n .pipe(Effect.mapError((error) => storeError(`storage failpoint ${location}`, error)));\n\n const materialize: ThreadStore[\"Service\"][\"materialize\"] = Effect.fnUntraced(function* (\n request: ThreadMaterialization,\n ) {\n const validated = yield* Schema.decodeEffect(Schema.toType(ThreadMaterialization))(\n request,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"validate materialization\", error)));\n\n const now = yield* Clock.currentTimeMillis;\n\n yield* hitFailpoint(\"materialize:before\");\n yield* journal\n .materialize(validated.threadId, new Date(now).toISOString())\n .pipe(Effect.mapError((error) => storeError(\"materialize thread\", error)));\n yield* hitFailpoint(\"materialize:after\");\n }, withStorageSpan(\"DoThreadStore.materialize\"));\n\n const append: ThreadStore[\"Service\"][\"append\"] = Effect.fnUntraced(\n function* (request: AppendRequest) {\n const validated = yield* PreparedAppend.capture(request);\n const observed = yield* requireThread(journal, validated.threadId);\n\n const { raw: rawRequest } = yield* prepareCanonicalAppend(validated).pipe(\n Effect.provideService(Crypto.Crypto, crypto),\n );\n\n yield* hitFailpoint(\"append:before\");\n\n const result = yield* journal.state.owner\n .withProgress(rawRequest.threadId, journal.append(rawRequest, observed))\n .pipe(\n Effect.mapError((error) => {\n if (isDoAppendConflict(error)) {\n return error.actualTailSequence !== undefined\n ? AppendConflict.make({\n threadId: validated.threadId,\n batchId: validated.batch.batchId,\n reason: error.reason,\n actualTailSequence: error.actualTailSequence,\n })\n : AppendConflict.make({\n threadId: validated.threadId,\n batchId: validated.batch.batchId,\n reason: error.reason,\n });\n }\n\n return storeError(\"append canonical batch\", error);\n }),\n Effect.flatMap((result) =>\n Schema.decodeEffect(AppendResult)(result).pipe(\n Effect.mapError((error) => schemaStoreError(\"decode append result\", error)),\n ),\n ),\n );\n\n yield* hitFailpoint(\"append:after\");\n\n return result;\n },\n withStorageSpan(\"DoThreadStore.append\", isAppendContention),\n );\n\n const loadRecords = Effect.fnUntraced(function* (request: RawReadRequest) {\n const result = yield* journal\n .read(request)\n .pipe(Effect.mapError((error) => storeError(\"read canonical records\", error)));\n\n return {\n count: result.count,\n records: result.records.pipe(\n Stream.mapError((error) => storeError(\"read canonical records\", error)),\n Stream.mapEffect(decodeEnvelope),\n ),\n };\n });\n\n const readEffect = Effect.fnUntraced(function* (request: ThreadReadRequest) {\n const validated = yield* Schema.decodeEffect(Schema.toType(ThreadReadRequest))(request).pipe(\n Effect.mapError((error) => schemaStoreError(\"validate thread read\", error)),\n );\n\n if (\"selection\" in validated) return Stream.fromIterable(yield* selectedReads.read(validated));\n yield* requireThread(journal, validated.threadId);\n\n const result = yield* loadRecords(\n RawReadRequest.make({\n threadId: validated.threadId,\n fromSequenceExclusive: validated.afterSequence ?? ZERO_CANONICAL_SEQUENCE,\n limit: validated.limit,\n }),\n );\n\n return result.records;\n });\n\n const read: ThreadStore[\"Service\"][\"read\"] = (request) => Stream.unwrap(readEffect(request));\n\n const observeEffect = Effect.fnUntraced(function* (request: ThreadObservation) {\n const validated = yield* Schema.decodeEffect(Schema.toType(ThreadObservation))(request).pipe(\n Effect.mapError((error) => schemaStoreError(\"validate thread observation\", error)),\n );\n\n yield* requireThread(journal, validated.threadId);\n const initialSequence = yield* parseOffset(validated.threadId, validated.afterOffset);\n const cursor = yield* Ref.make(initialSequence);\n let polls = 0;\n let emptyPolls = 0;\n let deliveredRecords = 0;\n\n const poll = Effect.fnUntraced(function* () {\n polls++;\n const fromSequenceExclusive = yield* Ref.get(cursor);\n\n const result = yield* loadRecords(\n RawReadRequest.make({\n threadId: validated.threadId,\n fromSequenceExclusive,\n limit: 1_024,\n }),\n );\n\n if (result.count === 0) {\n emptyPolls++;\n yield* Effect.sleep(config.observationPollInterval);\n\n return Stream.empty;\n }\n\n return result.records.pipe(\n Stream.tap((record) => {\n deliveredRecords++;\n\n return Ref.set(cursor, record.sequence);\n }),\n );\n });\n\n return Stream.fromEffectRepeat(poll()).pipe(\n Stream.flatten,\n Stream.ensuring(\n Effect.suspend(() =>\n Effect.annotateCurrentSpan({\n \"effect_agent.observation.polls\": polls,\n \"effect_agent.observation.empty_polls\": emptyPolls,\n \"effect_agent.observation.records\": deliveredRecords,\n }),\n ),\n ),\n );\n });\n\n const observe: ThreadStore[\"Service\"][\"observe\"] = (request) =>\n Stream.unwrap(observeEffect(request)).pipe(Stream.withSpan(\"DoThreadStore.observe\"));\n\n const transfer = yield* makeSqlThreadImport({\n owner: journal.state.owner,\n offsetPrefix: DO_OFFSET_PREFIX,\n maxValueBytes: config.maxStoredValueBytes,\n // Import establishes a new sequence space; discard derivatives in this same transaction.\n afterImport: ({ result }) =>\n Effect.gen(function* () {\n const prefix = promptCheckpointPrefix(result.threadId);\n\n yield* sql`DELETE FROM effect_agent_meta WHERE key >= ${prefix} AND key < ${prefix + \"~\"}`;\n // Closed imported history must not emit historical lifecycle notifications again.\n if (journal.lifecycle !== undefined)\n yield* sql`INSERT INTO effect_agent_lifecycle_cursors(thread_id, through_sequence) VALUES (${result.threadId}, ${result.tailSequence})`;\n }).pipe(\n Effect.catchTag(\"SqlError\", (cause) => storeError(\"rebuild imported derivatives\", cause)),\n ),\n afterThreadRead: hitFailpoint(\"export:after-thread-read\"),\n read: (body) =>\n journal.owner.transaction(body).pipe(\n Effect.provideService(SqlClientService.SqlClient, sql),\n Effect.catchIf(isSqlError, (cause) => storeError(\"export transaction\", cause)),\n ),\n write: (body) =>\n journal.owner.transaction(body.pipe(Effect.tap(() => journal.state.invalidate))).pipe(\n Effect.provideService(SqlClientService.SqlClient, sql),\n Effect.catchIf(isSqlError, (cause) => storeError(\"import transaction\", cause)),\n ),\n });\n\n const inspectTail: ThreadStore[\"Service\"][\"inspectTail\"] = Effect.fnUntraced(function* (\n request: ThreadTailRequest,\n ) {\n const validated = yield* Schema.decodeEffect(Schema.toType(ThreadTailRequest))(request).pipe(\n Effect.mapError((error) => schemaStoreError(\"validate tail inspection\", error)),\n );\n\n const thread = yield* requireThread(journal, validated.threadId);\n\n return ThreadTail.make({\n threadId: validated.threadId,\n tailSequence: thread.tail_sequence,\n });\n });\n\n const saveCheckpoint: ThreadCheckpoints[\"save\"] = Effect.fnUntraced(function* (\n request: SaveCheckpointRequest,\n ) {\n const validated = yield* Schema.decodeEffect(Schema.toType(SaveCheckpointRequest))(\n request,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"validate checkpoint\", error)));\n\n const thread = yield* requireThread(journal, validated.checkpoint.threadId);\n\n if (validated.checkpoint.throughSequence > thread.tail_sequence) {\n return yield* CheckpointRejected.make({\n threadId: validated.checkpoint.threadId,\n reason: \"ahead-of-tail\",\n });\n }\n\n yield* requireBatchBoundary(\n journal,\n validated.checkpoint.threadId,\n validated.checkpoint.throughSequence,\n );\n const checkpointJson = yield* encodeCheckpoint(validated.checkpoint);\n\n const raw = RawCheckpoint.make({\n threadId: validated.checkpoint.threadId,\n throughSequence: validated.checkpoint.throughSequence,\n checkpointJson,\n });\n\n yield* hitFailpoint(\"save-checkpoint:before\");\n yield* journal.saveCheckpoint(raw).pipe(\n Effect.mapError((error) =>\n isDoCheckpointConflict(error)\n ? CheckpointRejected.make({\n threadId: validated.checkpoint.threadId,\n reason: error.reason,\n })\n : storeError(\"save checkpoint\", error),\n ),\n );\n yield* hitFailpoint(\"save-checkpoint:after\");\n });\n\n const loadCheckpoint: ThreadCheckpoints[\"load\"] = Effect.fnUntraced(function* (\n request: LoadCheckpointRequest,\n ) {\n const validated = yield* Schema.decodeEffect(Schema.toType(LoadCheckpointRequest))(\n request,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"validate checkpoint lookup\", error)));\n\n const thread = yield* requireThread(journal, validated.threadId);\n\n const rows = yield* journal\n .loadCheckpoint(validated.threadId, validated.atOrBeforeSequence ?? thread.tail_sequence)\n .pipe(Effect.mapError((error) => storeError(\"load checkpoint\", error)));\n\n if (rows.length === 0) return Option.none();\n if (rows.length !== 1) {\n return yield* ThreadStoreError.make({\n operation: \"load checkpoint\",\n message: `Expected at most one checkpoint row but found ${rows.length}.`,\n });\n }\n const row = rows[0];\n const checkpoint = yield* decodeCheckpoint(row.checkpoint_json);\n\n if (\n row.thread_id !== validated.threadId ||\n checkpoint.threadId !== row.thread_id ||\n checkpoint.throughSequence !== row.through_sequence\n ) {\n return yield* ThreadStoreError.make({\n operation: \"load checkpoint\",\n message: \"Stored checkpoint metadata does not match its canonical row.\",\n });\n }\n\n yield* requireBatchBoundary(journal, checkpoint.threadId, checkpoint.throughSequence);\n\n return Option.some(checkpoint);\n });\n\n const selectedReads = yield* makeSelectedReads(decodeEnvelope).pipe(\n Effect.provideService(SelectedReadOwner, {\n snapshot: journal.state.read,\n tail: (threadId) =>\n journal.getThread(threadId).pipe(\n Effect.flatMap((rows) =>\n Schema.decodeEffect(\n Schema.UndefinedOr(\n Schema.Struct({\n tail_sequence: CanonicalSequence,\n }),\n ),\n )(rows[0]),\n ),\n Effect.mapError((error) => storeError(\"native thread tail\", error)),\n ),\n }),\n );\n\n const threadStore = ThreadStore.of({\n archives: journal.archives,\n work: journal.work.storage,\n ...(journal.lifecycle === undefined\n ? {}\n : { lifecyclePublications: journal.lifecycle.storage }),\n readIdentity: selectedReads.readIdentity,\n readExecution: (request) =>\n journal.state.read(\n requireThread(journal, request.threadId).pipe(\n Effect.andThen(journal.readExecution(request)),\n ),\n ),\n readWorkerCapacity: selectedReads.readWorkerCapacity,\n verification: transfer.verification,\n countPeerMessages: selectedReads.countPeerMessages,\n append,\n export: transfer.export,\n inspectTail,\n materialize,\n observe,\n read,\n readPrompt: (request) => Stream.fromIterableEffect(selectedReads.readPrompt(request)),\n checkpoints: { save: saveCheckpoint, load: loadCheckpoint },\n promptCheckpoints: makePromptCheckpoints(sql, journal, config.maxStoredValueBytes),\n });\n\n return Context.make(ThreadStore, threadStore).pipe(\n Context.add(ThreadImport, transfer.importer),\n Context.add(StorageOwner, journal.state.owner),\n );\n});\n\n/**\n * Durable Object Thread Store implementation with configuration, failpoint, SQL, and\n * Crypto authority kept visible in its input channel.\n */\nexport const threadStoreLayer: Layer.Layer<\n ThreadStore | ThreadReader | ThreadImport | StorageOwner,\n DoStorageInitializationError,\n DoStorageConfig | DoStorageFailpoint | SqlClientService.SqlClient | Crypto.Crypto\n> = ThreadReader.layer().pipe(Layer.provideMerge(Layer.effectContext(makeServices())));\n\n/**\n * Validated Durable Object storage configuration Layer with the documented defaults applied.\n * Shared by the ThreadStore and SubmissionLedger convenience layers so their defaults\n * cannot drift.\n */\nexport const storageConfigLayer = (\n options: DoStorageOptions,\n): Layer.Layer<DoStorageConfig, DoStorageError> =>\n Layer.effect(DoStorageConfig)(\n Schema.decodeEffect(DoStorageConfigValue)({\n observationPollInterval: options.observationPollInterval ?? 25,\n maxStoredValueBytes: options.maxStoredValueBytes ?? DEFAULT_MAX_STORED_VALUE_BYTES,\n verifyOnOpen: options.verifyOnOpen ?? false,\n }).pipe(\n Effect.mapError((error) =>\n DoStorageError.make({\n cause: error,\n operation: \"configure Durable Object storage\",\n message: error.message,\n }),\n ),\n ),\n );\n\n/** The failpoint Layer selected by convenience options: explicit handler or the no-op default. */\nexport const storageFailpointLayer = (\n options: DoStorageOptions,\n): Layer.Layer<DoStorageFailpoint> =>\n options.failpoint === undefined\n ? DoStorageFailpoint.layer\n : Layer.succeed(DoStorageFailpoint)({ hit: options.failpoint });\n\n/**\n * A composition-root convenience Layer for canonical Threads inside one Durable Object,\n * built over `ctx.storage`. Durable accepted work is served by the separate SubmissionLedger\n * port; point both at the SAME `ctx.storage` so both share the same scoped storage owner\n * (ADR-0011 D7's \"same file\" rule, transposed to one object's private database).\n */\nexport const layer = (\n options: DoStorageOptions,\n): Layer.Layer<\n ThreadStore | ThreadReader | ThreadImport | StorageOwner,\n DoStorageInitializationError\n> =>\n Layer.unwrap(\n Effect.map(DoStorageConfig, (config) =>\n threadStoreLayer.pipe(\n Layer.provide(\n Layer.mergeAll(\n Layer.succeed(DoStorageConfig)(config),\n storageFailpointLayer(options),\n SqliteClient.layer({ storage: options.storage }),\n BrowserCrypto.layer,\n ),\n ),\n ),\n ),\n ).pipe(Layer.provide(storageConfigLayer(options)));\n\n/** Read a quiesced current-layout Object without initializing its layout or ownership. */\nexport const exportThread = Effect.fn(\"DoThreadStore.exportThread\")(function* (\n options: Pick<DoStorageOptions, \"storage\">,\n request: ThreadExportRequest,\n) {\n yield* checkExportSource(request.threadId);\n\n return yield* Effect.gen(function* () {\n const sql = yield* SqlClientService.SqlClient;\n const state = yield* ownedState(sql);\n\n return yield* state\n .transaction(\n Effect.gen(function* () {\n yield* readDoStorageHeader();\n\n const transfer = yield* makeSqlThreadImport({\n owner: state.owner,\n offsetPrefix: DO_OFFSET_PREFIX,\n read: (body) => body,\n write: () => Effect.die(\"A read-only exporter cannot import\"),\n });\n\n return yield* transfer.export(request);\n }),\n )\n .pipe(\n Effect.catchTag(\"SqlError\", (cause) =>\n DoStorageError.make({\n operation: \"export Thread snapshot\",\n message: cause.message,\n cause,\n }),\n ),\n );\n }).pipe(\n Effect.provide(\n Layer.merge(SqliteClient.layer({ storage: options.storage }), BrowserCrypto.layer),\n ),\n );\n});\n\n/**\n * Discard the Object's derived thread and ledger state after direct SQL maintenance.\n * Quiesce port operations during the raw write and invalidation, and enroll the write with\n * the host mutation gate. Ordinary ThreadStore/SubmissionLedger writes maintain this view.\n */\nexport const invalidate = invalidateOwnedState;\n\n/** Share the Object's transaction gate with owner-local SQL Memory compositions. */\nexport const sqlOwnerLayer = Layer.effectContext(\n Effect.flatMap(SqlClientService.SqlClient, ownedState).pipe(\n Effect.map((state) =>\n Context.make(SqlStorageOwner, state).pipe(Context.add(StorageOwner, state.owner)),\n ),\n ),\n);\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"do-journal-_MdLGTd3.mjs","names":["isSqlError","SqlClient"],"sources":["../src/internal/storage-span.ts","../src/internal/do-journal.ts"],"sourcesContent":["import { Effect, Predicate, Result } from \"effect\";\n\ntype Tagged = { readonly _tag: string; readonly reason?: unknown };\n\nexport const isAppendContention = (error: Tagged): boolean =>\n (error._tag === \"DoAppendConflict\" || error._tag === \"AppendConflict\") && error.reason === \"tail\";\n\n/** Expected refusals remain typed at the port, but are outcomes of the storage operation. */\nexport const storageResult = <A, E extends Tagged, R>(\n effect: Effect.Effect<A, E, R>,\n expected: (error: E) => boolean,\n) =>\n effect.pipe(\n Effect.map(Result.succeed),\n Effect.catchIf(expected, (error) => Effect.succeed(Result.fail(error))),\n );\n\n/** Only error discriminants enter telemetry; messages, SQL, identities and payloads do not. */\nexport const annotateStorageError = (error: Tagged) =>\n Effect.annotateCurrentSpan({\n \"error.type\": error._tag,\n ...(Predicate.hasProperty(error, \"cause\") &&\n Predicate.hasProperty(error.cause, \"_tag\") &&\n typeof error.cause._tag === \"string\"\n ? { \"error.cause.type\": error.cause._tag }\n : {}),\n });\n\nexport const withStorageSpan =\n (name: string, expected: (error: Tagged) => boolean = () => false) =>\n <A, E extends Tagged, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>\n storageResult(effect, expected).pipe(\n Effect.tap((result) =>\n Result.isFailure(result)\n ? Effect.annotateCurrentSpan({ \"storage.outcome\": result.failure._tag })\n : Effect.void,\n ),\n Effect.tapError(annotateStorageError),\n Effect.withSpan(name),\n Effect.flatMap(Effect.fromResult),\n );\n","import {\n makeCanonicalStorage,\n recordBatchId,\n} from \"@yielded/agent-storage-sql/sql-canonical-storage\";\nimport type { RawAppendRequest } from \"@yielded/agent-storage-sql/sql-journal\";\nimport { makeSqlExecutions } from \"@yielded/agent-storage-sql/sql-journal\";\nimport {\n makeSqlLifecyclePublication,\n type SqlLifecycleRetainMany,\n SqlLifecycleSource,\n SqlLifecycleRetainer,\n} from \"@yielded/agent-storage-sql/sql-lifecycle-publication\";\nimport { SqlStorageProgress } from \"@yielded/agent-storage-sql/sql-storage-progress\";\nimport {\n canonicalRecordJson,\n makeSqlThreadArchiveRange,\n} from \"@yielded/agent-storage-sql/sql-thread-archive-range\";\nimport { makeSqlThreadWork } from \"@yielded/agent-storage-sql/sql-thread-work\";\nimport { ThreadId } from \"@yielded/agent/identifiers\";\nimport {\n LifecyclePublicationFact,\n LifecyclePublicationError,\n} from \"@yielded/agent/lifecycle-publication\";\nimport { CanonicalRecord, CanonicalSequence } from \"@yielded/agent/records\";\nimport { SqlStorageOwner } from \"@yielded/agent/sql-memory-store\";\nimport {\n type AppendConflict,\n ThreadStoreDiagnostic,\n ThreadStoreError,\n} from \"@yielded/agent/thread-store\";\nimport { Cause, Clock, Effect, Option, Schema, Stream } from \"effect\";\nimport * as SqlClient from \"effect/sql/SqlClient\";\nimport { SqlError } from \"effect/sql/SqlError\";\n\nimport {\n type DoStorageFailpointError,\n DoAppendConflict,\n DoCheckpointConflict,\n DoStorageCorruptionError,\n DoStorageError,\n DoValueBoundExceeded,\n type DoStorageFailpointLocation,\n} from \"../DoStorageError.ts\";\nimport { ensureDoStorageLayout } from \"./migrations.ts\";\nimport { ownedState, ownedRows, type OwnedState } from \"./owned-state.ts\";\nimport {\n isAppendContention,\n annotateStorageError,\n storageResult,\n withStorageSpan,\n} from \"./storage-span.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_IDENTIFIER_LENGTH = 1_024;\nconst MAX_READ_PAGE_JSON_BYTES = 4 * 1024 * 1024;\n// A shared isolate budget permits multi-page hydration without multiplying its\n// retained payload by the number of resident Durable Object instances.\nconst MAX_RECORD_CACHE_JSON_BYTES = 8 * 1024 * 1024;\nconst MAX_RECORD_CACHE_ENTRIES = 4_096;\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 ThreadRow extends Schema.Class<ThreadRow>(\"ThreadRow\")({\n thread_id: BoundedIdentifier,\n created_at: Schema.NullOr(Schema.NonEmptyString.check(Schema.isMaxLength(128))),\n tail_sequence: CanonicalSequence,\n}) {}\n\nconst threadRows = ownedRows(\n ThreadRow,\n \"effect_agent_threads\",\n (row) => row.thread_id,\n \"thread_id\",\n);\n\nclass RecordRow extends Schema.Class<RecordRow>(\"RecordRow\")({\n batch_id: Schema.fromJsonString(BoundedIdentifier),\n thread_id: BoundedIdentifier,\n record_id: Schema.fromJsonString(BoundedIdentifier),\n record_json: BoundedStoredText,\n sequence: CanonicalSequence,\n}) {}\n\ninterface RecordCacheEntry {\n readonly row: RecordRow;\n readonly bytes: number;\n readonly evict: () => void;\n}\n\n// Entries retain only their local row map, never a storage owner or incarnation.\nconst isolateRecords = new Map<RecordCacheEntry, true>();\nlet isolateRecordBytes = 0;\n\nconst releaseRecord = (entry: RecordCacheEntry) => {\n if (!isolateRecords.delete(entry)) return;\n isolateRecordBytes -= entry.bytes;\n entry.evict();\n};\n\nconst recordCaches = new WeakMap<OwnedState, ReturnType<typeof makeRecordCache>>();\n\nconst makeRecordCache = () => {\n const records = new Map<string, RecordCacheEntry>();\n const key = (thread: string, sequence: number) => JSON.stringify([thread, sequence]);\n\n return {\n clear: () => {\n for (const entry of records.values()) releaseRecord(entry);\n },\n get: (thread: string, sequence: number) => records.get(key(thread, sequence))?.row,\n prefix: (thread: string, through: number): ReadonlyArray<RecordRow> | undefined => {\n const prefix: Array<RecordRow> = [];\n\n for (let sequence = 1; sequence <= through; sequence++) {\n const row = records.get(key(thread, sequence));\n\n if (row === undefined) return undefined;\n prefix.push(row.row);\n }\n\n return prefix;\n },\n put: (row: RecordRow, capturedBytes?: number) => {\n const id = key(row.thread_id, row.sequence);\n const prior = records.get(id);\n\n if (prior?.row === row) return;\n const size = capturedBytes ?? storedTextBytes(row.record_json);\n\n if (prior !== undefined) releaseRecord(prior);\n\n const entry: RecordCacheEntry = {\n row,\n bytes: size,\n evict: () => records.delete(id),\n };\n\n records.set(id, entry);\n isolateRecords.set(entry, true);\n isolateRecordBytes += size;\n while (\n isolateRecordBytes > MAX_RECORD_CACHE_JSON_BYTES ||\n isolateRecords.size > MAX_RECORD_CACHE_ENTRIES\n ) {\n const oldest = isolateRecords.keys().next().value;\n\n if (oldest === undefined) break;\n releaseRecord(oldest);\n }\n },\n };\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 through_sequence: CanonicalSequence,\n}) {}\n\nconst LifecycleCursorRow = Schema.Struct({\n thread_id: BoundedIdentifier,\n through_sequence: CanonicalSequence,\n});\n\nconst lifecycleCursorRows = ownedRows(\n LifecycleCursorRow,\n \"effect_agent_lifecycle_cursors\",\n (row) => row.thread_id,\n \"thread_id\",\n);\n\nconst initializedLifecycleSources = new WeakSet<OwnedState>();\n\nexport type { RawAppendRequest } from \"@yielded/agent-storage-sql/sql-journal\";\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}) {}\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 throughSequence: CanonicalSequence,\n}) {}\n\ntype AppendError =\n | ThreadStoreError\n | DoAppendConflict\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 diagnostic: ThreadStoreDiagnostic.make({\n causeTag: error._tag,\n operation,\n issueTag: error.reason._tag,\n }),\n });\n\n/** Decode raw Durable Object SQLite rows against a Schema, reporting failures as typed corruption. */\nexport const decodeRows = <A, I>(\n schema: Schema.Codec<ReadonlyArray<A>, ReadonlyArray<I>>,\n table: string,\n rowKey: string,\n rows: unknown,\n decoder: string = table,\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: \"Stored rows do not satisfy the storage schema\",\n diagnostic: ThreadStoreDiagnostic.make({\n causeTag: error._tag,\n operation: \"decode storage rows\",\n decoder,\n issueTag: error.issue._tag,\n }),\n }),\n ),\n Effect.tapError((error) =>\n Effect.annotateCurrentSpan({\n \"storage.failure.operation\": error.diagnostic?.operation,\n \"storage.failure.cause\": error.diagnostic?.causeTag,\n \"storage.failure.decoder\": decoder,\n \"storage.failure.issue\": error.diagnostic?.issueTag,\n }),\n ),\n );\n\n/** Decode exactly one raw row against a Schema, reporting failures as typed corruption. */\nexport const decodeSingleRow = <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/** Open a validated layout and bind this Object's storage owner. */\nconst ensureCurrentStorage = Effect.fnUntraced(function* (\n sql: SqlClient.SqlClient,\n failpoint: DoJournalFailpoint = noFailpoint,\n maxStoredValueBytes: number,\n) {\n yield* ensureDoStorageLayout().pipe(Effect.provideService(SqlClient.SqlClient, sql));\n\n const state = yield* ownedState(sql);\n const owner = (yield* SqlStorageOwner) ?? state;\n let journal: DoJournal | undefined;\n\n const lifecycle = yield* makeSqlLifecyclePublication(undefined, maxStoredValueBytes).pipe(\n Effect.provideService(SqlStorageOwner, owner),\n Effect.provideService(SqlLifecycleSource, {\n beforeRetain: (threadId) =>\n Effect.suspend(() =>\n journal === undefined\n ? Effect.fail(LifecyclePublicationError.make({ reason: \"unavailable\" }))\n : journal.flushCanonical(threadId),\n ),\n beforePending: Effect.suspend(() =>\n journal === undefined\n ? Effect.fail(LifecyclePublicationError.make({ reason: \"unavailable\" }))\n : journal.flushPublications(),\n ),\n }),\n Effect.provideService(SqlClient.SqlClient, sql),\n Effect.mapError((cause) =>\n DoStorageError.make({\n operation: \"initialize lifecycle publication\",\n message: \"Native publication storage unavailable\",\n cause,\n }),\n ),\n );\n\n journal = yield* makeJournal(sql, failpoint, maxStoredValueBytes, lifecycle, state).pipe(\n Effect.provideService(SqlStorageOwner, owner),\n );\n if (lifecycle !== undefined) yield* journal.initializeLifecycleSource();\n\n return journal;\n});\n\nconst makeJournal = (\n sql: SqlClient.SqlClient,\n failpoint: DoJournalFailpoint,\n maxStoredValueBytes: number,\n lifecycle: Effect.Success<ReturnType<typeof makeSqlLifecyclePublication>>,\n state: OwnedState,\n) =>\n Effect.gen(function* () {\n const owner = (yield* SqlStorageOwner) ?? state;\n const progress = yield* SqlStorageProgress;\n\n const work = yield* makeSqlThreadWork({\n read: (body) => state.read(body),\n write: (body) =>\n owner.transaction(body.pipe(Effect.tap(() => state.invalidate))).pipe(\n Effect.provideService(SqlClient.SqlClient, sql),\n Effect.catchTag(\"SqlError\", (cause) =>\n ThreadStoreError.make({\n operation: \"rebuild Thread work\",\n message: \"Thread work transaction failed\",\n cause,\n }),\n ),\n ),\n }).pipe(Effect.provideService(SqlClient.SqlClient, sql));\n\n yield* Effect.acquireRelease(\n Effect.sync(() => state.invalidators.add(work.invalidate)),\n () => Effect.sync(() => state.invalidators.delete(work.invalidate)),\n );\n\n const workFailure = (cause: unknown) =>\n DoStorageError.make({\n operation: \"publish Thread work\",\n message: \"Canonical work metadata could not be published\",\n cause,\n });\n\n const executions = yield* makeSqlExecutions().pipe(\n Effect.provideService(SqlClient.SqlClient, sql),\n );\n\n const executionConflict = <A>(effect: Effect.Effect<A, AppendConflict | ThreadStoreError>) =>\n effect.pipe(\n Effect.catchTag(\"AppendConflict\", (error) =>\n Effect.fail(\n DoAppendConflict.make({\n reason: error.reason,\n message: \"Active execution conflicts with the captured commit\",\n ...(error.actualTailSequence === undefined\n ? {}\n : { actualTailSequence: error.actualTailSequence }),\n }),\n ),\n ),\n );\n\n const threads = threadRows(state, sql);\n const cursors = lifecycleCursorRows(state, sql);\n let records = recordCaches.get(state);\n\n if (records === undefined) {\n records = makeRecordCache();\n recordCaches.set(state, records);\n state.invalidators.add(records.clear);\n }\n const recordCache = records;\n\n const archives = yield* makeSqlThreadArchiveRange({\n read: (body) => state.read(body),\n write: (body) =>\n owner.transaction(body.pipe(Effect.tap(() => state.invalidate))).pipe(\n Effect.provideService(SqlClient.SqlClient, sql),\n Effect.catchTag(\"SqlError\", (cause) =>\n ThreadStoreError.make({\n operation: \"archive write\",\n message: \"Archive transaction failed.\",\n cause,\n }),\n ),\n ),\n }).pipe(Effect.provideService(SqlClient.SqlClient, sql));\n\n const recordJson = canonicalRecordJson(sql);\n\n const physical = yield* makeCanonicalStorage().pipe(\n Effect.provideService(SqlClient.SqlClient, sql),\n );\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 actualBytes = storedTextBytes(value),\n ): Effect.Effect<void, DoValueBoundExceeded> => {\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 * The shared local owner gate covers the transaction and acknowledgement.\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. Expected outcomes may be captured only when every such refusal precedes\n * mutation; real faults still roll back. Successful preflight reads never authorize a write.\n */\n const withWriteTransaction =\n (operation: string, expected: (error: { readonly _tag: string }) => boolean = () => false) =>\n <A, E extends { readonly _tag: string }>(\n effect: Effect.Effect<A, E>,\n ): Effect.Effect<A, E | DoStorageError> =>\n state.owner.withMutation(owner.transaction(storageResult(effect, expected))).pipe(\n Effect.provideService(SqlClient.SqlClient, sql),\n Effect.mapError((error) => (isSqlError(error) ? storageError(operation)(error) : error)),\n Effect.tapError(annotateStorageError),\n Effect.withSpan(\"DoJournal.withWriteTransaction\", { attributes: { operation } }),\n Effect.flatMap(Effect.fromResult),\n );\n\n const materialize = Effect.fnUntraced(function* (\n threadId: string,\n createdAt: string,\n ): Effect.fn.Return<void, DoStorageCorruptionError | DoStorageError | DoValueBoundExceeded> {\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 // Refusals and idempotent materialization need no transaction. Recheck before writes.\n const current = yield* getThread(threadId);\n\n if (current.length === 1) {\n return;\n }\n yield* withWriteTransaction(\"materialize transaction\")(\n Effect.gen(function* () {\n const existingRows = yield* getThread(threadId);\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 ) VALUES (\n ${threadId},\n ${createdAt},\n 0\n ) ON CONFLICT(thread_id) DO UPDATE SET created_at=excluded.created_at\n WHERE effect_agent_threads.created_at IS NULL\n RETURNING *`.pipe(\n threads.write,\n Effect.mapError((error) =>\n error._tag === \"SqlError\" ? storageError(\"materialize thread\")(error) : error,\n ),\n );\n\n if (lifecycle !== undefined)\n yield* sql`INSERT INTO effect_agent_lifecycle_cursors (thread_id, through_sequence)\n VALUES (${threadId}, 0) RETURNING *`.pipe(\n cursors.write,\n Effect.mapError((error) =>\n error._tag === \"SqlError\"\n ? storageError(\"initialize lifecycle source\")(error)\n : error,\n ),\n );\n\n return;\n }\n }),\n );\n }, withStorageSpan(\"DoJournal.materialize\"));\n\n const getThread = Effect.fnUntraced(function* (threadId: string) {\n return (yield* threads\n .by(\"thread_id\", threadId)\n .pipe(\n Effect.mapError((error) =>\n error._tag === \"SqlError\" ? storageError(\"read thread\")(error) : error,\n ),\n )).filter((row) => row.thread_id === threadId && row.created_at !== null);\n });\n\n const hasRecord = Effect.fnUntraced(function* (threadId: string, recordId: string) {\n const thread = (yield* getThread(threadId))[0];\n const prefix = recordCache.prefix(threadId, thread?.tail_sequence ?? 0);\n\n if (prefix !== undefined) return prefix.some((row) => row.record_id === recordId);\n\n const rows = yield* sql`SELECT record_id FROM effect_agent_canonical_records\n WHERE thread_id = ${threadId} AND record_id = ${JSON.stringify(recordId)}`.pipe(\n Effect.mapError(storageError(\"read canonical record identity\")),\n );\n\n return rows.length > 0;\n });\n\n const prepareAppend = Effect.fnUntraced(function* (request: RawAppendRequest) {\n if (\n request.threadId.length > MAX_IDENTIFIER_LENGTH ||\n request.batchId.length > MAX_IDENTIFIER_LENGTH ||\n request.executionWrites.some(\n ({ update }) => update.checkpoint.progress.runId.length > MAX_IDENTIFIER_LENGTH,\n ) ||\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 // Archives store the full batch as one value, so their ceiling also bounds hot appends.\n // The trusted append SPI pairs captured JSON with its exact UTF-8 width.\n yield* checkValueBound(\"append canonical batch\", request.batchJson, request.batchBytes);\n for (const record of request.records) {\n if (record.recordBytes > maxStoredValueBytes)\n return yield* DoValueBoundExceeded.make({\n actualBytes: record.recordBytes,\n maxBytes: maxStoredValueBytes,\n operation: \"append canonical record\",\n });\n }\n for (const write of request.executionWrites)\n yield* checkValueBound(\"commit active execution\", write.json, write.bytes);\n\n const recordIds: Array<string> = 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 return request;\n });\n\n const appendPrepared = Effect.fnUntraced(function* (\n request: RawAppendRequest,\n ): Effect.fn.Return<RawAppendResult, AppendError> {\n const recordIds: Array<string> = request.records.map((record) => record.recordId);\n const threadRows = yield* getThread(request.threadId);\n\n const thread = threadRows.length === 1 ? threadRows[0] : undefined;\n\n if (thread === undefined)\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_threads\",\n rowKey: request.threadId,\n message: `Expected exactly one row but found ${threadRows.length}.`,\n });\n\n const prefix = recordCache.prefix(request.threadId, thread.tail_sequence);\n\n const replay = yield* executionConflict(executions.replay(request));\n\n if (replay !== undefined) return RawAppendResult.make(replay);\n\n const existing =\n prefix !== undefined && !prefix.some((row) => row.batch_id === request.batchId)\n ? undefined\n : yield* archives.replay(request.threadId, request.batchId);\n\n if (existing !== undefined) {\n if (existing.batch_json !== request.batchJson) {\n return yield* DoAppendConflict.make({\n message: `Batch ${request.batchId} already exists with different canonical content.`,\n reason: \"batch-content\",\n });\n }\n\n return RawAppendResult.make({\n firstSequence: existing.first_sequence,\n lastSequence: existing.last_sequence,\n replayed: true,\n });\n }\n\n yield* executionConflict(executions.rejectSuperseded(request));\n\n if (request.expectedTailSequence !== thread.tail_sequence) {\n return yield* DoAppendConflict.make({\n message:\n `Expected tail ${request.expectedTailSequence} ` + `but found ${thread.tail_sequence}.`,\n reason: \"tail\",\n actualTailSequence: thread.tail_sequence,\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 prefix === undefined ? [] : prefix.filter((row) => recordIds.includes(row.record_id));\n\n for (const chunk of prefix === undefined\n ? chunked(recordIds, MAX_BOUND_PARAMETERS - 10)\n : []) {\n const existingRecordRows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n sequence,\n record_id,\n ${recordBatchId(sql)} AS batch_id,\n ${recordJson} AS record_json\n FROM effect_agent_canonical_records\n WHERE thread_id = ${request.threadId}\n AND record_id IN ${sql.in(chunk.map((id) => JSON.stringify(id)))}\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.decodeEffect(CanonicalSequence)(\n thread.tail_sequence + (request.records.length === 0 ? 0 : 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.decodeEffect(CanonicalSequence)(\n thread.tail_sequence + request.records.length,\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* executionConflict(executions.validate(request));\n\n const result = RawAppendResult.make({\n firstSequence,\n lastSequence,\n replayed: false,\n });\n\n if (request.records.length > 0) {\n yield* sql`\n INSERT INTO effect_agent_canonical_batches (\n thread_id,\n batch_id,\n first_sequence,\n last_sequence,\n producer_id_json\n ) VALUES (\n ${request.threadId},\n ${JSON.stringify(request.batchId)},\n ${firstSequence},\n ${lastSequence},\n ${request.producerIdJson}\n )\n `.pipe(Effect.mapError(storageError(\"insert canonical batch\")));\n }\n yield* failpoint(\"append:after-batch-insert\");\n\n const physicalRecords = yield* physical.records(\n request.threadId,\n firstSequence,\n request.records,\n );\n\n const records = physicalRecords.map(({ columns, memberships }, index) => ({\n record: request.records[index]!,\n canonical: request.records[index]!.canonical,\n row: columns,\n memberships,\n }));\n\n // Captured scalar locators avoid parsing canonical JSON under the writer.\n // Eighteen bound columns per row stay within workerd's statement limit.\n for (const group of chunked(records, Math.floor(MAX_BOUND_PARAMETERS / 18))) {\n yield* sql`INSERT INTO effect_agent_canonical_records ${sql.insert(group.map(({ row }) => row))}`.pipe(\n Effect.mapError(storageError(\"insert canonical records\")),\n );\n\n const memberships = group.flatMap(({ memberships }) => memberships);\n\n for (const members of chunked(memberships, Math.floor(MAX_BOUND_PARAMETERS / 3)))\n yield* sql`INSERT INTO effect_agent_record_runs ${sql.insert(members)}`.pipe(\n Effect.mapError(storageError(\"index canonical Run membership\")),\n );\n for (const { row, record } of group) {\n recordCache.put(\n RecordRow.make({\n ...row,\n record_id: record.recordId,\n batch_id: request.batchId,\n record_json: record.recordJson,\n sequence: Schema.decodeSync(CanonicalSequence)(row.sequence),\n }),\n record.recordBytes,\n );\n yield* failpoint(\"append:after-record-insert\");\n }\n }\n\n if (request.records.length > 0) {\n const workFields = yield* work\n .apply(\n yield* Schema.decodeEffect(ThreadId)(request.threadId).pipe(\n Effect.mapError(workFailure),\n ),\n firstSequence,\n request.records.map((record) => record.canonical),\n )\n .pipe(Effect.mapError(workFailure));\n\n yield* sql`UPDATE effect_agent_threads SET ${sql.update({ tail_sequence: lastSequence, ...workFields })}\n WHERE thread_id=${request.threadId} RETURNING *`.pipe(\n threads.write,\n Effect.mapError((error) =>\n error._tag === \"SqlError\" ? storageError(\"advance thread tail\")(error) : error,\n ),\n );\n }\n yield* executionConflict(executions.commit(request, result));\n if (request.executionWrites.length > 0) yield* failpoint(\"append:after-record-insert\");\n if (\n lifecycle !== undefined &&\n request.executionWrites.some(({ update }) =>\n update.facts.some(({ payload }) => payload._tag === \"RunStarted\"),\n )\n )\n yield* flushCanonical(request.threadId).pipe(\n Effect.provideService(SqlLifecycleRetainer, { retainMany: lifecycle.retainMany }),\n Effect.mapError((cause) =>\n DoStorageError.make({\n operation: \"retain lifecycle start prefix\",\n message: \"Lifecycle start intent could not be retained\",\n cause,\n }),\n ),\n );\n for (const { update } of request.executionWrites) {\n for (const fact of update.facts) {\n if (\n lifecycle !== undefined &&\n Schema.is(Schema.toType(LifecyclePublicationFact))(fact.payload)\n )\n yield* lifecycle\n .retain({\n id: JSON.stringify([request.threadId, \"record\", fact.recordId]),\n ownerThreadId: request.threadId,\n canonicalSequence: lastSequence,\n createdAt: fact.createdAt,\n fact: fact.payload,\n })\n .pipe(\n Effect.mapError((cause) =>\n DoStorageError.make({\n operation: \"retain operational lifecycle\",\n message: cause.message,\n cause,\n }),\n ),\n );\n }\n }\n yield* failpoint(\"append:after-tail-update\");\n\n // Retain one start prefix atomically with its canonical proof, before model/tool\n // execution. Later facts stay journal-backed until the settlement publication wave.\n if (\n lifecycle !== undefined &&\n records.some(\n ({ canonical: { payload } }) =>\n payload._tag === \"RunStarted\" || payload._tag === \"SubagentStarted\",\n )\n )\n yield* flushCanonical(request.threadId).pipe(\n Effect.provideService(SqlLifecycleRetainer, { retainMany: lifecycle.retainMany }),\n Effect.mapError((cause) =>\n DoStorageError.make({\n operation: \"retain lifecycle start prefix\",\n message: \"Lifecycle start intent could not be retained\",\n cause,\n }),\n ),\n );\n\n yield* progress.committed(\"canonical\").pipe(\n Effect.catchCause((cause) =>\n Effect.failCause(\n Cause.map(cause, (error) =>\n DoStorageError.make({\n operation: \"enroll canonical progress\",\n message: error.message,\n cause: error,\n }),\n ),\n ),\n ),\n );\n\n return result;\n });\n\n const append = Effect.fnUntraced(\n function* (\n request: RawAppendRequest,\n observed: ThreadRow,\n ): Effect.fn.Return<RawAppendResult, AppendError> {\n yield* prepareAppend(request);\n // The facade already read this tail. Reject a known stale writer without opening a\n // transaction; a matching tail is still checked atomically below. Replays precede tail\n // conflicts, preserving retry identity even after the log has advanced.\n if (request.records.length > 0 && request.expectedTailSequence !== observed.tail_sequence) {\n const batches = yield* sql`\n SELECT batch_id FROM effect_agent_canonical_batches\n WHERE thread_id = ${request.threadId} AND batch_id = ${JSON.stringify(request.batchId)}\n UNION ALL SELECT last_commit_id FROM effect_agent_executions\n WHERE thread_id = ${request.threadId} AND last_commit_id = ${request.batchId}\n LIMIT 1\n `.pipe(Effect.mapError(storageError(\"preflight append replay\")));\n\n // A possible replay still checks exact content in the transaction.\n if (batches.length === 0) {\n return yield* DoAppendConflict.make({\n reason: \"tail\",\n message: \"The canonical tail has advanced.\",\n actualTailSequence: observed.tail_sequence,\n });\n }\n }\n\n return yield* withWriteTransaction(\n \"append transaction\",\n isAppendContention,\n )(appendPrepared(request));\n },\n withStorageSpan(\"DoJournal.append\", isAppendContention),\n );\n\n const read = Effect.fnUntraced(function* (request: RawReadRequest) {\n const thread = (yield* getThread(request.threadId))[0];\n\n const through = Math.min(\n thread?.tail_sequence ?? 0,\n request.fromSequenceExclusive + request.limit,\n );\n\n const cached: Array<RecordRow> = [];\n\n for (let sequence = request.fromSequenceExclusive + 1; sequence <= through; sequence++) {\n const record = recordCache.get(request.threadId, sequence);\n\n if (record === undefined) break;\n cached.push(record);\n }\n if (cached.length === Math.max(0, through - request.fromSequenceExclusive)) {\n return { count: cached.length, records: Stream.fromIterable(cached) };\n }\n\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(${recordJson} 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 \"ReadPlanRow\",\n );\n\n const mismatch = () =>\n DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_records\",\n rowKey: `${request.threadId}>${request.fromSequenceExclusive}`,\n message:\n \"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.fnUntraced(function* (page: ReadPage) {\n const rows = yield* sql<Record<string, unknown>>`\n SELECT thread_id, sequence, record_id, ${recordBatchId(sql)} AS batch_id, ${recordJson} AS 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 \"RecordRow\",\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 for (const row of decoded) recordCache.put(row);\n\n return decoded;\n });\n\n return {\n count: plan.length,\n records: Stream.fromIterable(pages).pipe(\n Stream.flatMap((page) => Stream.fromIterableEffect(state.read(readPage(page)))),\n ),\n };\n });\n\n const saveCheckpoint = Effect.fnUntraced(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* getThread(checkpoint.threadId);\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 reason: \"ahead-of-tail\",\n message:\n `Checkpoint sequence ${checkpoint.throughSequence} is after canonical tail ` +\n `${thread.tail_sequence}.`,\n });\n }\n\n if (!(yield* isBatchBoundary(checkpoint.threadId, checkpoint.throughSequence))) {\n return yield* DoCheckpointConflict.make({\n reason: \"not-batch-boundary\",\n message: \"Checkpoint sequence is not the end of a complete canonical batch.\",\n });\n }\n\n const checkpointRows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n through_sequence,\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 (existing[0].checkpoint_json !== checkpoint.checkpointJson) {\n return yield* DoCheckpointConflict.make({\n reason: \"corrupt\",\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 checkpoint_json\n ) VALUES (\n ${checkpoint.threadId},\n ${checkpoint.throughSequence},\n ${checkpoint.checkpointJson}\n )\n `.pipe(Effect.mapError(storageError(\"insert checkpoint\")));\n }),\n );\n });\n\n const loadCheckpoint = Effect.fnUntraced(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 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 isBatchBoundary = Effect.fnUntraced(function* (\n threadId: string,\n sequence: CanonicalSequence,\n ) {\n if (sequence === 0) return true;\n\n const rows = yield* sql<Record<string, unknown>>`\n SELECT last_sequence FROM effect_agent_canonical_batches\n WHERE thread_id = ${threadId}\n AND batch_id = (\n SELECT ${recordBatchId(sql)} FROM effect_agent_canonical_records\n WHERE thread_id = ${threadId} AND sequence = ${sequence}\n )\n AND last_sequence = ${sequence}\n `.pipe(Effect.mapError(storageError(\"read canonical batch boundary\")));\n\n const batches = yield* decodeRows(\n Schema.Array(Schema.Struct({ last_sequence: CanonicalSequence })),\n \"effect_agent_canonical_batches\",\n `${threadId}/${sequence}`,\n rows,\n );\n\n return batches.length === 1;\n });\n\n const sourceFailure = (cause: unknown) =>\n LifecyclePublicationError.make({ reason: \"unavailable\", cause });\n\n const sourceThreads = Effect.fnUntraced(function* () {\n const all = yield* threads.matching(\n \"lifecycle-owners\",\n (row) => row.created_at !== null,\n sql`SELECT * FROM effect_agent_threads WHERE created_at IS NOT NULL LIMIT 129`,\n 128,\n );\n\n if (all.length <= 128) return all;\n\n // Large custom hosts hydrate only owners whose journal has an unmaterialized suffix.\n return yield* Schema.decodeUnknownEffect(Schema.Array(ThreadRow))(\n yield* sql`SELECT t.* FROM effect_agent_threads t LEFT JOIN effect_agent_lifecycle_cursors c ON c.thread_id=t.thread_id\n WHERE t.created_at IS NOT NULL AND (c.thread_id IS NULL OR t.tail_sequence > c.through_sequence) ORDER BY t.thread_id LIMIT 128`,\n );\n });\n\n const initializeLifecycleSource = Effect.fnUntraced(function* () {\n if (initializedLifecycleSources.has(state)) return;\n yield* state\n .transaction(\n Effect.gen(function* () {\n const existing =\n yield* sql`SELECT name FROM sqlite_master WHERE name='effect_agent_lifecycle_cursors'`;\n\n if (existing.length === 0) {\n yield* sql`CREATE TABLE effect_agent_lifecycle_cursors (\n thread_id TEXT PRIMARY KEY, through_sequence INTEGER NOT NULL\n )`;\n // Existing inline writers already retained their facts. Enabling publication on an\n // old store starts here too; it does not publish historical facts retroactively.\n }\n // New Threads created with publication disabled have no cursor. Never advance\n // existing cursors: they can owe intent from an interrupted Attempt.\n yield* sql`INSERT INTO effect_agent_lifecycle_cursors(thread_id, through_sequence)\n SELECT thread_id, tail_sequence FROM effect_agent_threads WHERE created_at IS NOT NULL\n ON CONFLICT(thread_id) DO NOTHING`;\n yield* sourceThreads();\n }),\n )\n .pipe(\n Effect.provideService(SqlClient.SqlClient, sql),\n Effect.mapError((cause) =>\n DoStorageError.make({\n operation: \"initialize lifecycle source\",\n message: \"Lifecycle source cursor unavailable\",\n cause,\n }),\n ),\n );\n initializedLifecycleSources.add(state);\n });\n\n /** The journal is durable intent; only the bounded publication wave materializes a write set. */\n const flushCanonical = Effect.fnUntraced(function* (threadId: string, maxRecords = Infinity) {\n const { retainMany } = yield* SqlLifecycleRetainer;\n const thread = (yield* getThread(threadId))[0];\n\n if (thread === undefined) return;\n const cursor = (yield* cursors.by(\"thread_id\", threadId))[0];\n\n if (cursor === undefined || cursor.through_sequence > thread.tail_sequence)\n return yield* LifecyclePublicationError.make({ reason: \"corrupt\" });\n let through = cursor.through_sequence;\n const bound = Math.min(thread.tail_sequence, through + maxRecords);\n\n while (through < bound) {\n const page = yield* read(\n RawReadRequest.make({\n threadId,\n fromSequenceExclusive: through,\n limit: Math.min(128, bound - through),\n }),\n );\n\n const facts: Array<Parameters<SqlLifecycleRetainMany>[0][number]> = [];\n let bytes = 0;\n\n yield* Stream.runForEach(page.records, (row) =>\n Effect.gen(function* () {\n const record = yield* Schema.decodeEffect(Schema.fromJsonString(CanonicalRecord))(\n row.record_json,\n );\n\n if (record.recordId !== row.record_id || row.sequence !== through + 1)\n return yield* LifecyclePublicationError.make({ reason: \"corrupt\" });\n if (Schema.is(Schema.toType(LifecyclePublicationFact))(record.payload)) {\n if (\n bytes + storedTextBytes(row.record_json) > MAX_READ_PAGE_JSON_BYTES &&\n facts.length > 0\n ) {\n yield* retainMany(facts);\n facts.length = 0;\n bytes = 0;\n }\n facts.push({\n id: JSON.stringify([threadId, \"record\", record.recordId]),\n ownerThreadId: yield* Schema.decodeEffect(ThreadId)(threadId),\n canonicalSequence: row.sequence,\n createdAt: record.createdAt,\n fact: record.payload,\n });\n bytes += storedTextBytes(row.record_json);\n }\n through = row.sequence;\n }),\n );\n if (page.count === 0) return yield* LifecyclePublicationError.make({ reason: \"corrupt\" });\n yield* retainMany(facts);\n yield* sql`UPDATE effect_agent_lifecycle_cursors SET through_sequence=${through} WHERE thread_id=${threadId} RETURNING *`.pipe(\n cursors.write,\n );\n }\n }, Effect.mapError(sourceFailure));\n\n const flushPublications = Effect.fnUntraced(function* () {\n let owners = 0;\n\n for (const thread of yield* sourceThreads()) {\n const cursor = (yield* cursors.by(\"thread_id\", thread.thread_id))[0];\n\n if (cursor !== undefined && cursor.through_sequence === thread.tail_sequence) continue;\n yield* flushCanonical(thread.thread_id, 1024);\n if (++owners === 4) break;\n }\n }, Effect.mapError(sourceFailure));\n\n const sourcePending = Effect.gen(function* () {\n for (const thread of yield* sourceThreads()) {\n const cursor = (yield* cursors.by(\"thread_id\", thread.thread_id))[0];\n\n if (cursor === undefined || cursor.through_sequence > thread.tail_sequence)\n return yield* LifecyclePublicationError.make({ reason: \"corrupt\" });\n if (cursor.through_sequence < thread.tail_sequence) return true;\n }\n\n return false;\n }).pipe(Effect.mapError(sourceFailure));\n\n const ownedLifecycle =\n lifecycle === undefined\n ? undefined\n : {\n ...lifecycle,\n storage: {\n ...lifecycle.storage,\n retainedPendingDeadline: lifecycle.storage.pendingDeadline,\n pendingDeadline: state.read(\n Effect.gen(function* () {\n const deadline = yield* lifecycle.storage.pendingDeadline;\n\n if (!(yield* sourcePending)) return deadline;\n const now = yield* Clock.currentTimeMillis;\n\n return Option.some(Option.isSome(deadline) ? Math.min(now, deadline.value) : now);\n }),\n ),\n },\n };\n\n return {\n archives: archives.storage,\n archiveRanges: archives,\n work,\n state,\n owner,\n threads,\n lifecycle: ownedLifecycle,\n initializeLifecycleSource,\n flushCanonical,\n flushPublications,\n append,\n prepareAppend,\n appendPrepared,\n checkCommitIntent: (request: RawAppendRequest) =>\n executionConflict(executions.checkCommitIntent(request)),\n readExecution: executions.read,\n checkValueBound,\n getThread,\n hasRecord,\n isBatchBoundary,\n loadCheckpoint,\n materialize,\n read: (request: RawReadRequest) => state.read(read(request)),\n saveCheckpoint,\n withWriteTransaction,\n } as const;\n });\n\nexport type DoJournal = Effect.Success<ReturnType<typeof makeJournal>>;\n\nexport const initializeDoJournal = ensureCurrentStorage;\n"],"mappings":"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"}