@effect-agent/storage-cloudflare 0.1.0-beta.50 → 0.1.0-beta.52
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.
- package/dist/DoScheduleStore.mjs +1 -1
- package/dist/DoScheduleStore.mjs.map +1 -1
- package/dist/{DoStorageVersion-KrYUXqeJ.d.mts → DoStorageVersion-DxqcVgDE.d.mts} +2 -2
- package/dist/DoStorageVersion.d.mts +1 -1
- package/dist/DoStorageVersion.mjs +2 -2
- package/dist/DoSubmissionLedger.mjs +35 -6
- package/dist/DoSubmissionLedger.mjs.map +1 -1
- package/dist/DoSubscriptionStore.mjs +8 -4
- package/dist/DoSubscriptionStore.mjs.map +1 -1
- package/dist/{DoThreadStore-D00TdRAa.mjs → DoThreadStore-JqjeFOga.mjs} +8 -8
- package/dist/{DoThreadStore-D00TdRAa.mjs.map → DoThreadStore-JqjeFOga.mjs.map} +1 -1
- package/dist/DoThreadStore.mjs +1 -1
- package/dist/PortProtocol.d.mts +25 -3
- package/dist/PortProtocol.mjs +2 -1
- package/dist/PortProtocol.mjs.map +1 -1
- package/dist/PortRouting.mjs +2 -2
- package/dist/PortRouting.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{migrations-Bo4GU-pp.mjs → migrations-B-jiT7vx.mjs} +9 -3
- package/dist/migrations-B-jiT7vx.mjs.map +1 -0
- package/package.json +1 -1
- package/src/DoScheduleStore.ts +1 -1
- package/src/DoSubmissionLedger.ts +61 -3
- package/src/DoSubscriptionStore.ts +8 -4
- package/src/PortProtocol.ts +2 -0
- package/src/PortRouting.ts +2 -1
- package/src/internal/migrations.ts +8 -1
- package/dist/migrations-Bo4GU-pp.mjs.map +0 -1
|
@@ -15,8 +15,12 @@ import {
|
|
|
15
15
|
AbortIntentRequest,
|
|
16
16
|
AdmissionAdmitted,
|
|
17
17
|
AdmissionConflict,
|
|
18
|
+
AdmissionFence,
|
|
19
|
+
AdmissionGroup,
|
|
20
|
+
AdmissionPolicyError,
|
|
18
21
|
AdmissionNotAdmitted,
|
|
19
22
|
AdmissionRequest,
|
|
23
|
+
SubmissionAdmissionFence,
|
|
20
24
|
AdmissionResult,
|
|
21
25
|
ApprovalConflict,
|
|
22
26
|
ApprovalDecisionCommand,
|
|
@@ -143,6 +147,8 @@ class SubmissionRow extends Schema.Class<SubmissionRow>("SubmissionRow")({
|
|
|
143
147
|
unknown_tool_call_ids_json: Schema.NullOr(BoundedStoredText),
|
|
144
148
|
parent_submission_id: Schema.NullOr(BoundedIdentifier),
|
|
145
149
|
parent_tool_call_id: Schema.NullOr(BoundedIdentifier),
|
|
150
|
+
admission_group: Schema.NullOr(AdmissionGroup),
|
|
151
|
+
admission_fence_json: Schema.NullOr(BoundedStoredText),
|
|
146
152
|
}) {}
|
|
147
153
|
|
|
148
154
|
class ChildReservationRow extends Schema.Class<ChildReservationRow>("ChildReservationRow")({
|
|
@@ -255,7 +261,9 @@ const SUBMISSION_COLUMNS = `
|
|
|
255
261
|
unknown_reason,
|
|
256
262
|
unknown_tool_call_ids_json,
|
|
257
263
|
parent_submission_id,
|
|
258
|
-
parent_tool_call_id
|
|
264
|
+
parent_tool_call_id,
|
|
265
|
+
admission_group,
|
|
266
|
+
admission_fence_json
|
|
259
267
|
`;
|
|
260
268
|
|
|
261
269
|
const CHILD_RESERVATION_COLUMNS = `
|
|
@@ -342,6 +350,7 @@ const makeServices = Effect.fn("DoSubmissionLedger.makeServices")(function* () {
|
|
|
342
350
|
const failpoint = yield* DoStorageFailpoint;
|
|
343
351
|
const sql = yield* SqlClientService.SqlClient;
|
|
344
352
|
const crypto = yield* Crypto.Crypto;
|
|
353
|
+
const admissionFence = yield* SubmissionAdmissionFence;
|
|
345
354
|
const journal = yield* initializeDoJournal(sql, failpoint.hit, config.maxStoredValueBytes);
|
|
346
355
|
|
|
347
356
|
const hitFailpoint = (
|
|
@@ -359,6 +368,7 @@ const makeServices = Effect.fn("DoSubmissionLedger.makeServices")(function* () {
|
|
|
359
368
|
A,
|
|
360
369
|
E extends
|
|
361
370
|
| AdmissionConflict
|
|
371
|
+
| AdmissionPolicyError
|
|
362
372
|
| ApprovalConflict
|
|
363
373
|
| ChildReservationConflict
|
|
364
374
|
| JoinedToHost
|
|
@@ -560,6 +570,14 @@ const makeServices = Effect.fn("DoSubmissionLedger.makeServices")(function* () {
|
|
|
560
570
|
receiptId: row.receipt_id,
|
|
561
571
|
state: row.state,
|
|
562
572
|
createdAt: row.created_at,
|
|
573
|
+
...(row.admission_group === null ? {} : { admissionGroup: row.admission_group }),
|
|
574
|
+
...(row.admission_fence_json === null
|
|
575
|
+
? {}
|
|
576
|
+
: {
|
|
577
|
+
admissionFence: yield* parseStoredJsonText(row.admission_fence_json).pipe(
|
|
578
|
+
Effect.mapError(internalFailure(operation)),
|
|
579
|
+
),
|
|
580
|
+
}),
|
|
563
581
|
...(row.settled_outcome === null ? {} : { settledOutcome: row.settled_outcome }),
|
|
564
582
|
...(row.ready_at === null ? {} : { readyAt: row.ready_at }),
|
|
565
583
|
...(row.parent_submission_id === null || row.parent_tool_call_id === null
|
|
@@ -1082,6 +1100,28 @@ const makeServices = Effect.fn("DoSubmissionLedger.makeServices")(function* () {
|
|
|
1082
1100
|
});
|
|
1083
1101
|
}
|
|
1084
1102
|
|
|
1103
|
+
const retainedFence =
|
|
1104
|
+
existing[0].admission_fence_json === null
|
|
1105
|
+
? undefined
|
|
1106
|
+
: yield* Schema.decodeEffect(Schema.fromJsonString(AdmissionFence))(
|
|
1107
|
+
existing[0].admission_fence_json,
|
|
1108
|
+
).pipe(Effect.mapError(internalFailure(operation)));
|
|
1109
|
+
|
|
1110
|
+
if (
|
|
1111
|
+
(existing[0].admission_group ?? undefined) !== validated.admissionGroup ||
|
|
1112
|
+
!Schema.toEquivalence(Schema.optional(AdmissionFence))(
|
|
1113
|
+
retainedFence,
|
|
1114
|
+
validated.admissionFence,
|
|
1115
|
+
)
|
|
1116
|
+
)
|
|
1117
|
+
return yield* AdmissionConflict.make({
|
|
1118
|
+
threadId: validated.threadId,
|
|
1119
|
+
principal: validated.principal,
|
|
1120
|
+
idempotencyKey: validated.idempotencyKey,
|
|
1121
|
+
existingInputDigest: existing[0].input_digest,
|
|
1122
|
+
attemptedInputDigest: validated.inputDigest,
|
|
1123
|
+
});
|
|
1124
|
+
|
|
1085
1125
|
return yield* decodeAdmissionResult({
|
|
1086
1126
|
submissionId: existing[0].submission_id,
|
|
1087
1127
|
receiptId: existing[0].receipt_id,
|
|
@@ -1091,6 +1131,20 @@ const makeServices = Effect.fn("DoSubmissionLedger.makeServices")(function* () {
|
|
|
1091
1131
|
}).pipe(Effect.mapError(internalFailure(operation)));
|
|
1092
1132
|
}
|
|
1093
1133
|
|
|
1134
|
+
yield* admissionFence.check(validated);
|
|
1135
|
+
if (validated.admissionGroup !== undefined) {
|
|
1136
|
+
const occupied = yield* sql<Record<string, unknown>>`
|
|
1137
|
+
SELECT submission_id FROM effect_agent_submissions
|
|
1138
|
+
WHERE thread_id=${validated.threadId} AND admission_group=${validated.admissionGroup} AND state<>'settled' LIMIT 1
|
|
1139
|
+
`.pipe(Effect.mapError(sqlFailure(operation)));
|
|
1140
|
+
|
|
1141
|
+
if (occupied.length > 0)
|
|
1142
|
+
return yield* AdmissionPolicyError.make({
|
|
1143
|
+
reason: "occupied",
|
|
1144
|
+
code: "admission-group",
|
|
1145
|
+
});
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1094
1148
|
const maxRows = yield* sql<Record<string, unknown>>`
|
|
1095
1149
|
SELECT COALESCE(MAX(queue_sequence), 0) AS max_queue_sequence
|
|
1096
1150
|
FROM effect_agent_submissions
|
|
@@ -1126,7 +1180,9 @@ const makeServices = Effect.fn("DoSubmissionLedger.makeServices")(function* () {
|
|
|
1126
1180
|
state,
|
|
1127
1181
|
created_at,
|
|
1128
1182
|
parent_submission_id,
|
|
1129
|
-
parent_tool_call_id
|
|
1183
|
+
parent_tool_call_id,
|
|
1184
|
+
admission_group,
|
|
1185
|
+
admission_fence_json
|
|
1130
1186
|
) VALUES (
|
|
1131
1187
|
${mintedSubmissionId},
|
|
1132
1188
|
${validated.threadId},
|
|
@@ -1142,7 +1198,9 @@ const makeServices = Effect.fn("DoSubmissionLedger.makeServices")(function* () {
|
|
|
1142
1198
|
'admitted',
|
|
1143
1199
|
${now.iso},
|
|
1144
1200
|
${validated.parentLinkage?.parentSubmissionId ?? null},
|
|
1145
|
-
${validated.parentLinkage?.parentToolCallId ?? null}
|
|
1201
|
+
${validated.parentLinkage?.parentToolCallId ?? null},
|
|
1202
|
+
${validated.admissionGroup ?? null},
|
|
1203
|
+
${validated.admissionFence === undefined ? null : JSON.stringify(validated.admissionFence)}
|
|
1146
1204
|
)
|
|
1147
1205
|
`.pipe(Effect.mapError(sqlFailure(operation)));
|
|
1148
1206
|
|
|
@@ -13,7 +13,7 @@ import { Context, Effect, Layer, Schema } from "effect";
|
|
|
13
13
|
import * as SqlClientService from "effect/unstable/sql/SqlClient";
|
|
14
14
|
import type { SqlError } from "effect/unstable/sql/SqlError";
|
|
15
15
|
|
|
16
|
-
const CURRENT_SUBSCRIPTION_STORE_VERSION =
|
|
16
|
+
const CURRENT_SUBSCRIPTION_STORE_VERSION = 3;
|
|
17
17
|
|
|
18
18
|
const ScanRow = Schema.Struct({
|
|
19
19
|
event_scan_cursor: Schema.String,
|
|
@@ -108,7 +108,7 @@ const initializeDoSubscriptionStore = Effect.fn("DoSubscriptionStore.initialize"
|
|
|
108
108
|
yield* sql`CREATE TABLE effect_agent_subscriptions (
|
|
109
109
|
tenant_id TEXT NOT NULL, source_address TEXT NOT NULL, owner_id TEXT NOT NULL, subscription_id TEXT NOT NULL,
|
|
110
110
|
ordinal INTEGER NOT NULL, source_name TEXT NOT NULL, source_version TEXT NOT NULL, matching_key TEXT NOT NULL,
|
|
111
|
-
state TEXT NOT NULL, expires_at_millis INTEGER NOT NULL
|
|
111
|
+
state TEXT NOT NULL, expires_at_millis INTEGER, recovery_at_millis INTEGER, recovery_present INTEGER NOT NULL DEFAULT 0, record_json TEXT NOT NULL,
|
|
112
112
|
PRIMARY KEY (tenant_id, source_address, owner_id, subscription_id), UNIQUE (tenant_id, source_address, ordinal)
|
|
113
113
|
)`.withoutTransform;
|
|
114
114
|
yield* sql`CREATE INDEX effect_agent_subscriptions_owner ON effect_agent_subscriptions (tenant_id, source_address, owner_id, ordinal)`
|
|
@@ -120,7 +120,7 @@ const initializeDoSubscriptionStore = Effect.fn("DoSubscriptionStore.initialize"
|
|
|
120
120
|
yield* sql`CREATE TABLE effect_agent_subscription_events (
|
|
121
121
|
tenant_id TEXT NOT NULL, source_address TEXT NOT NULL, event_id TEXT NOT NULL, source_name TEXT NOT NULL,
|
|
122
122
|
source_version TEXT NOT NULL, matching_key TEXT NOT NULL, payload_digest TEXT NOT NULL, cutoff INTEGER NOT NULL,
|
|
123
|
-
cursor INTEGER NOT NULL, routing_complete INTEGER NOT NULL, next_attempt_at_millis INTEGER NOT NULL, record_json TEXT NOT NULL,
|
|
123
|
+
cursor INTEGER NOT NULL, routing_complete INTEGER NOT NULL, tombstone INTEGER NOT NULL DEFAULT 0, next_attempt_at_millis INTEGER NOT NULL, record_json TEXT NOT NULL,
|
|
124
124
|
PRIMARY KEY (tenant_id, source_address, event_id)
|
|
125
125
|
)`.withoutTransform;
|
|
126
126
|
yield* sql`CREATE INDEX effect_agent_subscription_events_pending ON effect_agent_subscription_events (tenant_id, source_address, routing_complete, next_attempt_at_millis, event_id)`
|
|
@@ -202,7 +202,11 @@ const makeSubscriptionStore = Effect.fn("DoSubscriptionStore.make")(function* (
|
|
|
202
202
|
SELECT next_attempt_at_millis AS deadline FROM effect_agent_subscription_events
|
|
203
203
|
WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address} AND routing_complete=0
|
|
204
204
|
UNION ALL SELECT next_attempt_at_millis FROM effect_agent_subscription_deliveries
|
|
205
|
-
WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address} AND
|
|
205
|
+
WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address} AND CASE WHEN json_valid(record_json) THEN
|
|
206
|
+
((state NOT IN ('delivered','refused') AND COALESCE(json_extract(record_json, '$.retry.parked'), 0)=0) OR (state='delivered' AND json_extract(record_json, '$.observeSettlement')=1))
|
|
207
|
+
ELSE state<>'refused' END
|
|
208
|
+
UNION ALL SELECT next_maintenance_at_millis FROM effect_agent_event_retention
|
|
209
|
+
WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address}
|
|
206
210
|
UNION ALL SELECT recovery_at_millis FROM effect_agent_subscriptions
|
|
207
211
|
WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address} AND state='active' AND recovery_at_millis IS NOT NULL
|
|
208
212
|
)
|
package/src/PortProtocol.ts
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
AbortCommand,
|
|
4
4
|
AbortIntent,
|
|
5
5
|
AdmissionConflict,
|
|
6
|
+
AdmissionPolicyError,
|
|
6
7
|
AdmissionRequest,
|
|
7
8
|
AdmissionResolution,
|
|
8
9
|
AdmissionResult,
|
|
@@ -281,6 +282,7 @@ export type PortResult = typeof PortResult.Type;
|
|
|
281
282
|
*/
|
|
282
283
|
export const PortFailure = Schema.Union([
|
|
283
284
|
AdmissionConflict,
|
|
285
|
+
AdmissionPolicyError,
|
|
284
286
|
SettlementConflict,
|
|
285
287
|
JoinedToHost,
|
|
286
288
|
LedgerError,
|
package/src/PortRouting.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AdmissionIndeterminate,
|
|
3
3
|
AdmissionConflict,
|
|
4
|
+
AdmissionPolicyError,
|
|
4
5
|
ChildAttachmentSnapshot,
|
|
5
6
|
JoinedToHost,
|
|
6
7
|
LedgerError,
|
|
@@ -482,7 +483,7 @@ const makeRoutedLedgerServices = Effect.fn("DoPortRouting.makeRoutedLedgerServic
|
|
|
482
483
|
request.threadId,
|
|
483
484
|
LedgerAdmitCall.make({ request }),
|
|
484
485
|
LedgerAdmitResult,
|
|
485
|
-
AdmissionConflict,
|
|
486
|
+
Schema.Union([AdmissionConflict, AdmissionPolicyError]),
|
|
486
487
|
).pipe(Effect.map((reply) => reply.result)),
|
|
487
488
|
|
|
488
489
|
markReady: (request) =>
|
|
@@ -3,7 +3,7 @@ import { Effect } from "effect";
|
|
|
3
3
|
import * as SqlClient from "effect/unstable/sql/SqlClient";
|
|
4
4
|
|
|
5
5
|
/** The current storage version recorded in `effect_agent_meta`. */
|
|
6
|
-
export const CurrentDoStorageVersion =
|
|
6
|
+
export const CurrentDoStorageVersion = 3;
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* The Thread Durable Object schema shares its thread and ledger tables with Node/SQLite.
|
|
@@ -108,6 +108,8 @@ export const doMigrations = SqliteMigrator.fromRecord({
|
|
|
108
108
|
unknown_tool_call_ids_json TEXT,
|
|
109
109
|
parent_submission_id TEXT,
|
|
110
110
|
parent_tool_call_id TEXT,
|
|
111
|
+
admission_group TEXT,
|
|
112
|
+
admission_fence_json TEXT,
|
|
111
113
|
UNIQUE (thread_id, principal, idempotency_key),
|
|
112
114
|
UNIQUE (thread_id, queue_sequence)
|
|
113
115
|
)
|
|
@@ -123,6 +125,11 @@ export const doMigrations = SqliteMigrator.fromRecord({
|
|
|
123
125
|
ON effect_agent_submissions (parent_submission_id)
|
|
124
126
|
`.withoutTransform;
|
|
125
127
|
|
|
128
|
+
yield* sql`
|
|
129
|
+
CREATE INDEX effect_agent_submissions_group
|
|
130
|
+
ON effect_agent_submissions (thread_id, admission_group, state)
|
|
131
|
+
`.withoutTransform;
|
|
132
|
+
|
|
126
133
|
yield* sql`
|
|
127
134
|
CREATE TABLE effect_agent_submission_ownership (
|
|
128
135
|
submission_id TEXT PRIMARY KEY NOT NULL,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"migrations-Bo4GU-pp.mjs","names":[],"sources":["../src/internal/migrations.ts"],"sourcesContent":["import { SqliteMigrator } from \"@effect/sql-sqlite-do\";\nimport { Effect } from \"effect\";\nimport * as SqlClient from \"effect/unstable/sql/SqlClient\";\n\n/** The current storage version recorded in `effect_agent_meta`. */\nexport const CurrentDoStorageVersion = 2;\n\n/**\n * The Thread Durable Object schema shares its thread and ledger tables with Node/SQLite.\n * Schedules and subscriptions use separate Durable Objects. Two DC-specific additions:\n *\n * 1. `effect_agent_meta` replaces `PRAGMA user_version` as the exact-or-fresh version gate —\n * a meta table is portable regardless of which PRAGMAs Durable Object SQL storage allows.\n * 2. `effect_agent_child_settlements` is the durable cross-store notification marker the\n * SubmissionLedger port contract mandates for cross-store adapters (`suspend`'s covering\n * check and `recordChildSettled`'s wake both consult it): parent and child Threads\n * live in different Durable Objects, so a child settlement reported before the parent's\n * suspend commits must be observable from the PARENT's own storage.\n */\nexport const doMigrations = SqliteMigrator.fromRecord({\n \"1_current_cloudflare_thread_object\": Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n\n yield* sql`\n CREATE TABLE effect_agent_threads (\n thread_id TEXT PRIMARY KEY NOT NULL,\n created_at TEXT NOT NULL,\n tail_sequence INTEGER NOT NULL,\n tail_digest TEXT NOT NULL,\n producer_epoch INTEGER NOT NULL\n )\n `.withoutTransform;\n\n yield* sql`\n CREATE TABLE effect_agent_canonical_batches (\n thread_id TEXT NOT NULL,\n batch_id TEXT NOT NULL,\n first_sequence INTEGER NOT NULL,\n last_sequence INTEGER NOT NULL,\n batch_digest TEXT NOT NULL,\n tail_digest TEXT NOT NULL,\n batch_json TEXT NOT NULL,\n PRIMARY KEY (thread_id, batch_id),\n FOREIGN KEY (thread_id)\n REFERENCES effect_agent_threads(thread_id)\n ON DELETE RESTRICT\n )\n `.withoutTransform;\n\n yield* sql`\n CREATE TABLE effect_agent_canonical_records (\n thread_id TEXT NOT NULL,\n sequence INTEGER NOT NULL,\n record_id TEXT NOT NULL,\n batch_id TEXT NOT NULL,\n record_json TEXT NOT NULL,\n PRIMARY KEY (thread_id, sequence),\n UNIQUE (thread_id, record_id),\n FOREIGN KEY (thread_id, batch_id)\n REFERENCES effect_agent_canonical_batches(thread_id, batch_id)\n ON DELETE RESTRICT\n )\n `.withoutTransform;\n\n yield* sql`\n CREATE INDEX effect_agent_canonical_records_batch\n ON effect_agent_canonical_records (thread_id, batch_id, sequence)\n `.withoutTransform;\n\n yield* sql`\n CREATE TABLE effect_agent_checkpoints (\n thread_id TEXT NOT NULL,\n through_sequence INTEGER NOT NULL,\n tail_digest TEXT NOT NULL,\n checkpoint_json TEXT NOT NULL,\n PRIMARY KEY (thread_id, through_sequence),\n FOREIGN KEY (thread_id)\n REFERENCES effect_agent_threads(thread_id)\n ON DELETE RESTRICT\n )\n `.withoutTransform;\n\n // Admission rows exist before Thread materialization (durability §4), so\n // thread_id intentionally carries no foreign key into effect_agent_threads.\n yield* sql`\n CREATE TABLE effect_agent_submissions (\n submission_id TEXT PRIMARY KEY NOT NULL,\n thread_id TEXT NOT NULL,\n queue_sequence INTEGER NOT NULL,\n principal TEXT NOT NULL,\n idempotency_key TEXT NOT NULL,\n agent_id TEXT NOT NULL,\n agent_digests_json TEXT NOT NULL,\n deployment_id TEXT NOT NULL,\n input_json TEXT NOT NULL,\n input_digest TEXT NOT NULL,\n receipt_id TEXT NOT NULL,\n state TEXT NOT NULL,\n settled_outcome TEXT,\n created_at TEXT NOT NULL,\n ready_at TEXT,\n input_applied_record_id TEXT,\n input_applied_sequence INTEGER,\n joined_host_submission_id TEXT,\n suspended_reason_json TEXT,\n suspended_at TEXT,\n unknown_reason TEXT,\n unknown_tool_call_ids_json TEXT,\n parent_submission_id TEXT,\n parent_tool_call_id TEXT,\n UNIQUE (thread_id, principal, idempotency_key),\n UNIQUE (thread_id, queue_sequence)\n )\n `.withoutTransform;\n\n yield* sql`\n CREATE INDEX effect_agent_submissions_joined_host\n ON effect_agent_submissions (joined_host_submission_id)\n `.withoutTransform;\n\n yield* sql`\n CREATE INDEX effect_agent_submissions_parent\n ON effect_agent_submissions (parent_submission_id)\n `.withoutTransform;\n\n yield* sql`\n CREATE TABLE effect_agent_submission_ownership (\n submission_id TEXT PRIMARY KEY NOT NULL,\n attempt_id TEXT NOT NULL,\n ownership_token TEXT NOT NULL,\n producer_epoch INTEGER NOT NULL,\n owner_producer_id TEXT NOT NULL,\n lease_expires_at TEXT NOT NULL,\n FOREIGN KEY (submission_id)\n REFERENCES effect_agent_submissions(submission_id)\n ON DELETE RESTRICT\n )\n `.withoutTransform;\n\n yield* sql`\n CREATE TABLE effect_agent_attempts (\n attempt_id TEXT PRIMARY KEY NOT NULL,\n submission_id TEXT NOT NULL,\n thread_id TEXT NOT NULL,\n owner_producer_id TEXT NOT NULL,\n producer_epoch INTEGER NOT NULL,\n claimed_at TEXT NOT NULL,\n FOREIGN KEY (submission_id)\n REFERENCES effect_agent_submissions(submission_id)\n ON DELETE RESTRICT\n )\n `.withoutTransform;\n\n yield* sql`\n CREATE TABLE effect_agent_settlement_reservations (\n submission_id TEXT PRIMARY KEY NOT NULL,\n settlement_id TEXT NOT NULL,\n outcome TEXT NOT NULL,\n record_id TEXT NOT NULL,\n record_json TEXT NOT NULL,\n record_digest TEXT NOT NULL,\n reserved_at TEXT NOT NULL,\n finalized_at TEXT,\n FOREIGN KEY (submission_id)\n REFERENCES effect_agent_submissions(submission_id)\n ON DELETE RESTRICT\n )\n `.withoutTransform;\n\n yield* sql`\n CREATE TABLE effect_agent_abort_intents (\n submission_id TEXT PRIMARY KEY NOT NULL,\n author TEXT NOT NULL,\n reason TEXT NOT NULL,\n requested_at TEXT NOT NULL,\n canonical_record_id TEXT,\n FOREIGN KEY (submission_id)\n REFERENCES effect_agent_submissions(submission_id)\n ON DELETE RESTRICT\n )\n `.withoutTransform;\n\n yield* sql`\n CREATE TABLE effect_agent_approval_decisions (\n submission_id TEXT NOT NULL,\n tool_call_id TEXT NOT NULL,\n decision TEXT NOT NULL,\n resolver TEXT NOT NULL,\n reason TEXT NOT NULL,\n decided_at TEXT NOT NULL,\n PRIMARY KEY (submission_id, tool_call_id),\n FOREIGN KEY (submission_id)\n REFERENCES effect_agent_submissions(submission_id)\n ON DELETE RESTRICT\n )\n `.withoutTransform;\n\n yield* sql`\n CREATE TABLE effect_agent_unknown_resolutions (\n submission_id TEXT NOT NULL,\n tool_call_id TEXT NOT NULL,\n author TEXT NOT NULL,\n reason TEXT NOT NULL,\n resolution_json TEXT NOT NULL,\n resolved_at TEXT NOT NULL,\n PRIMARY KEY (submission_id, tool_call_id),\n FOREIGN KEY (submission_id)\n REFERENCES effect_agent_submissions(submission_id)\n ON DELETE RESTRICT\n )\n `.withoutTransform;\n\n yield* sql`\n CREATE TABLE effect_agent_child_reservations (\n reservation_id TEXT PRIMARY KEY NOT NULL,\n parent_submission_id TEXT NOT NULL,\n parent_tool_call_id TEXT NOT NULL,\n child_submission_id TEXT,\n status TEXT NOT NULL,\n allocation_json TEXT NOT NULL,\n allocation_digest TEXT NOT NULL,\n accounting_json TEXT,\n reserved_at TEXT NOT NULL,\n release_began_at TEXT,\n released_at TEXT,\n UNIQUE (parent_submission_id, parent_tool_call_id),\n FOREIGN KEY (parent_submission_id)\n REFERENCES effect_agent_submissions(submission_id)\n ON DELETE RESTRICT\n )\n `.withoutTransform;\n\n // Durable cross-store child-settlement notification marker (parent-side; the child's row\n // lives in ANOTHER Durable Object). child_outcome is nullable: the notification command\n // carries identities only, and the child's canonical Settlement stays the outcome\n // authority (DUR-015). No foreign keys: the parent row is checked by the operation, and\n // the child row is intentionally foreign.\n yield* sql`\n CREATE TABLE effect_agent_child_settlements (\n parent_submission_id TEXT NOT NULL,\n child_submission_id TEXT NOT NULL,\n child_outcome TEXT,\n recorded_at TEXT NOT NULL,\n PRIMARY KEY (parent_submission_id, child_submission_id)\n )\n `.withoutTransform;\n\n yield* sql`\n CREATE TABLE effect_agent_meta (\n key TEXT PRIMARY KEY NOT NULL,\n value TEXT NOT NULL\n )\n `.withoutTransform;\n\n yield* sql`\n INSERT INTO effect_agent_meta (key, value)\n VALUES ('storage_version', ${String(CurrentDoStorageVersion)})\n `.withoutTransform;\n }),\n});\n"],"mappings":";;;;;AAKA,MAAa,0BAA0B;;;;;;;;;;;;;AAcvC,MAAa,eAAe,eAAe,WAAW,EACpD,sCAAsC,OAAO,IAAI,aAAa;CAC5D,MAAM,MAAM,OAAO,UAAU;CAE7B,OAAO,GAAG;;;;;;;;MAQR;CAEF,OAAO,GAAG;;;;;;;;;;;;;;MAcR;CAEF,OAAO,GAAG;;;;;;;;;;;;;MAaR;CAEF,OAAO,GAAG;;;MAGR;CAEF,OAAO,GAAG;;;;;;;;;;;MAWR;CAIF,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MA6BR;CAEF,OAAO,GAAG;;;MAGR;CAEF,OAAO,GAAG;;;MAGR;CAEF,OAAO,GAAG;;;;;;;;;;;;MAYR;CAEF,OAAO,GAAG;;;;;;;;;;;;MAYR;CAEF,OAAO,GAAG;;;;;;;;;;;;;;MAcR;CAEF,OAAO,GAAG;;;;;;;;;;;MAWR;CAEF,OAAO,GAAG;;;;;;;;;;;;;MAaR;CAEF,OAAO,GAAG;;;;;;;;;;;;;MAaR;CAEF,OAAO,GAAG;;;;;;;;;;;;;;;;;;MAkBR;CAOF,OAAO,GAAG;;;;;;;;MAQR;CAEF,OAAO,GAAG;;;;;MAKR;CAEF,OAAO,GAAG;;mCAEqB,OAAA,CAA8B,EAAE;MAC7D;AACJ,CAAC,EACH,CAAC"}
|