import { assert, it } from "@effect/vitest"; import { EventId, CheckpointId, CheckpointRef, CheckpointScopeId, MessageId, type ModelSelection, NodeId, ProjectId, ProviderDriverKind, ProviderInstanceId, ProviderSessionId, ProviderThreadId, ProviderTurnId, RunAttemptId, RunId, ThreadId, TurnItemId, } from "@t3tools/contracts"; import * as DateTime from "effect/DateTime"; import * as Effect from "effect/Effect"; import * as Layer from "effect/Layer"; import * as Schema from "effect/Schema"; import * as SqlClient from "effect/unstable/sql/SqlClient"; import { SqlitePersistenceMemory } from "../persistence/Layers/Sqlite.ts"; import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; import { isTurnItemAtOrBeforeRun, ProjectionStoreV2, ProjectionStoreThreadNotFoundError, layer as projectionStoreLayer, } from "./ProjectionStore.ts"; import { buildBoundedThreadProjection, decodeThreadHistoryCursor, selectHistoryPageFromCursor, THREAD_HISTORY_PAGE_POLICY, } from "./threadHistoryPaging.ts"; const TestLayer = Layer.mergeAll( projectionStoreLayer.pipe(Layer.provideMerge(SqlitePersistenceMemory)), SqlitePersistenceMemory, ); const modelSelection = { instanceId: ProviderInstanceId.make("codex"), model: "gpt-5.4", } satisfies ModelSelection; const driver = ProviderDriverKind.make("codex"); const providerInstanceId = modelSelection.instanceId; const encodeUnknownJsonString = Schema.encodeSync(Schema.fromJsonString(Schema.Unknown)); it("includes imported runless history when selecting fork context through a run", () => { const firstRunId = RunId.make("run:projection-imported-fork:1"); const secondRunId = RunId.make("run:projection-imported-fork:2"); const runOrdinalById = new Map([ [firstRunId, 1], [secondRunId, 2], ]); assert.isTrue( isTurnItemAtOrBeforeRun({ historyOrigin: "v1_import", itemRunId: null, runOrdinalById, sourceRunOrdinal: 1, }), ); assert.isFalse( isTurnItemAtOrBeforeRun({ historyOrigin: undefined, itemRunId: null, runOrdinalById, sourceRunOrdinal: 1, }), ); assert.isTrue( isTurnItemAtOrBeforeRun({ historyOrigin: "v1_import", itemRunId: firstRunId, runOrdinalById, sourceRunOrdinal: 1, }), ); assert.isFalse( isTurnItemAtOrBeforeRun({ historyOrigin: "v1_import", itemRunId: secondRunId, runOrdinalById, sourceRunOrdinal: 1, }), ); }); it.layer(TestLayer)("ProjectionStoreV2", (it) => { it.effect("preserves stored provider usage when a terminal update omits it", () => Effect.gen(function* () { const projectionStore = yield* ProjectionStoreV2; const now = yield* DateTime.now; const threadId = ThreadId.make("thread:provider-usage-reload"); const providerThreadId = ProviderThreadId.make("provider-thread:provider-usage-reload"); const providerTurnId = ProviderTurnId.make("provider-turn:provider-usage-reload"); const nodeId = NodeId.make("node:provider-usage-reload"); const initialUsage = { usedTokens: 12_000, maxTokens: 200_000, inputTokens: 11_000, outputTokens: 1_000, updatedAt: "2026-08-29T12:00:00.000Z", } as const; const replacementUsage = { usedTokens: 18_000, maxTokens: 200_000, inputTokens: 16_000, outputTokens: 2_000, updatedAt: "2026-08-29T12:00:01.000Z", } as const; yield* projectionStore.apply({ id: EventId.make("event:provider-usage-reload:thread"), type: "thread.created", threadId, occurredAt: now, payload: { createdBy: "user", creationSource: "web", id: threadId, projectId: ProjectId.make("project:provider-usage-reload"), title: "Provider usage reload", providerInstanceId, modelSelection, runtimeMode: "full-access", interactionMode: "default", branch: null, worktreePath: null, activeProviderThreadId: null, lineage: { parentThreadId: null, relationshipToParent: null, rootThreadId: threadId }, forkedFrom: null, createdAt: now, updatedAt: now, archivedAt: null, settledOverride: null, settledAt: null, lastVisitedAt: null, deletedAt: null, }, }); const providerTurn = { id: providerTurnId, providerThreadId, nodeId, runAttemptId: null, nativeTurnRef: null, ordinal: 1, status: "running" as const, startedAt: now, completedAt: null, }; yield* projectionStore.apply({ id: EventId.make("event:provider-usage-reload:running"), type: "provider-turn.updated", threadId, nodeId, driver, occurredAt: now, payload: { ...providerTurn, tokenUsage: initialUsage }, }); yield* projectionStore.apply({ id: EventId.make("event:provider-usage-reload:completed"), type: "provider-turn.updated", threadId, nodeId, driver, occurredAt: now, payload: { ...providerTurn, status: "completed", completedAt: now }, }); const reloaded = yield* projectionStore.getThreadProjection(threadId); assert.deepEqual(reloaded.providerTurns[0]?.tokenUsage, initialUsage); assert.strictEqual(reloaded.providerTurns[0]?.status, "completed"); yield* projectionStore.apply({ id: EventId.make("event:provider-usage-reload:replacement"), type: "provider-turn.updated", threadId, nodeId, driver, occurredAt: now, payload: { ...providerTurn, status: "completed", completedAt: now, tokenUsage: replacementUsage, }, }); const replaced = yield* projectionStore.getThreadProjection(threadId); assert.deepEqual(replaced.providerTurns[0]?.tokenUsage, replacementUsage); }), ); it.effect("reads a fixed SQL turn-item window for long histories and repeated clients", () => Effect.gen(function* () { const projectionStore = yield* ProjectionStoreV2; const sql = yield* SqlClient.SqlClient; const now = yield* DateTime.now; const nowIso = DateTime.formatIso(now); const threadId = ThreadId.make("thread:bounded-sql-history"); yield* projectionStore.apply({ id: EventId.make("event:bounded-sql-history:thread"), type: "thread.created", threadId, occurredAt: now, payload: { createdBy: "user", creationSource: "web", id: threadId, projectId: ProjectId.make("project:bounded-sql-history"), title: "Bounded SQL history", providerInstanceId, modelSelection, runtimeMode: "full-access", interactionMode: "default", branch: null, worktreePath: null, activeProviderThreadId: null, lineage: { parentThreadId: null, relationshipToParent: null, rootThreadId: threadId }, forkedFrom: null, createdAt: now, updatedAt: now, archivedAt: null, settledOverride: null, settledAt: null, lastVisitedAt: null, deletedAt: null, }, }); for (let ordinal = 1; ordinal <= 1_000; ordinal += 1) { const id = `turn-item:bounded-sql-history:${ordinal}`; const runId = `run:bounded-sql-history:${ordinal}`; yield* sql` INSERT INTO orchestration_v2_projection_runs ( run_id, thread_id, ordinal, provider, provider_thread_id, status, requested_at, completed_at, payload_json ) VALUES ( ${runId}, ${threadId}, ${ordinal}, 'codex', NULL, 'completed', ${nowIso}, ${nowIso}, ${encodeUnknownJsonString({ id: runId, threadId, ordinal, providerInstanceId, modelSelection, providerThreadId: null, userMessageId: `message:bounded-sql-history:${ordinal}`, rootNodeId: `node:bounded-sql-history:${ordinal}`, activeAttemptId: null, status: "completed", requestedAt: nowIso, startedAt: nowIso, completedAt: nowIso, checkpointId: null, contextHandoffId: null, })} ) `; yield* sql` INSERT INTO orchestration_v2_projection_turn_items ( turn_item_id, thread_id, run_id, node_id, provider_thread_id, provider_turn_id, parent_item_id, ordinal, type, status, updated_at, payload_json ) VALUES ( ${id}, ${threadId}, ${runId}, NULL, NULL, NULL, NULL, ${ordinal}, 'command_execution', 'completed', ${nowIso}, ${encodeUnknownJsonString({ id, threadId, runId, nodeId: null, providerThreadId: null, providerTurnId: null, nativeItemRef: null, parentItemId: null, ordinal, status: "completed", title: `command ${ordinal}`, input: `echo ${ordinal}`, output: "ok", exitCode: 0, startedAt: nowIso, completedAt: nowIso, updatedAt: nowIso, type: "command_execution", })} ) `; } const snapshots = yield* Effect.all( Array.from({ length: 4 }, () => projectionStore.getThreadSnapshotWindow(threadId, { rowLimit: 76 }), ), { concurrency: 4 }, ); for (const snapshot of snapshots) { assert.lengthOf(snapshot.projection.turnItems, 76); assert.lengthOf(snapshot.projection.runs, 76); assert.lengthOf(snapshot.projection.visibleTurnItems, 76); assert.strictEqual(snapshot.projection.turnItems[0]?.ordinal, 925); assert.strictEqual(snapshot.projection.turnItems.at(-1)?.ordinal, 1_000); } const retainedRequestPlan = yield* sql<{ readonly detail: string }>` EXPLAIN QUERY PLAN WITH selected AS ( SELECT run_id, type FROM orchestration_v2_projection_turn_items WHERE thread_id = ${threadId} ORDER BY ordinal DESC, turn_item_id DESC LIMIT 77 ) SELECT request.payload_json FROM orchestration_v2_projection_turn_items AS request WHERE request.run_id IN ( SELECT run_id FROM selected WHERE type = 'run_interrupt_result' AND run_id IS NOT NULL ) AND request.type = 'run_interrupt_request' `; assert.isTrue( retainedRequestPlan.some((row) => row.detail.includes("orchestration_v2_projection_turn_items_run_ordinal_idx"), ), ); const older = yield* projectionStore.getThreadSnapshotWindow(threadId, { rowLimit: 76, anchorItemId: TurnItemId.make("turn-item:bounded-sql-history:925"), }); assert.lengthOf(older.projection.turnItems, 76); assert.lengthOf(older.projection.runs, 76); assert.strictEqual(older.projection.turnItems[0]?.ordinal, 850); assert.strictEqual(older.projection.turnItems.at(-1)?.ordinal, 925); const sqlPageLimit = THREAD_HISTORY_PAGE_POLICY.maxItems + 2; const initialSnapshot = yield* projectionStore.getThreadSnapshotWindow(threadId, { rowLimit: sqlPageLimit, }); const initialPage = buildBoundedThreadProjection({ projection: initialSnapshot.projection, snapshotSequence: initialSnapshot.snapshotSequence, }); const loadedIds = initialPage.projection.visibleTurnItems.map((row) => String(row.sourceItemId), ); let cursor = initialPage.historyCursor; let pageCount = 1; while (cursor !== null) { const anchorItemId = TurnItemId.make(decodeThreadHistoryCursor(cursor).si); const snapshot = yield* projectionStore.getThreadSnapshotWindow(threadId, { rowLimit: sqlPageLimit, anchorItemId, }); const page = selectHistoryPageFromCursor({ items: snapshot.projection.visibleTurnItems, cursor, snapshotSequence: snapshot.snapshotSequence, }); loadedIds.push(...page.items.map((row) => String(row.sourceItemId))); pageCount += 1; cursor = page.nextCursor; } assert.isAtLeast(pageCount, 4); assert.lengthOf(loadedIds, 1_000); assert.strictEqual(new Set(loadedIds).size, 1_000); assert.deepEqual( loadedIds.toSorted( (left, right) => Number(left.split(":").at(-1)) - Number(right.split(":").at(-1)), ), Array.from({ length: 1_000 }, (_, index) => `turn-item:bounded-sql-history:${index + 1}`), ); const hiddenRunId = RunId.make("run:bounded-sql-history:hidden-suffix"); yield* sql` INSERT INTO orchestration_v2_projection_runs ( run_id, thread_id, ordinal, provider, provider_thread_id, status, requested_at, completed_at, payload_json ) VALUES ( ${hiddenRunId}, ${threadId}, 1001, 'codex', NULL, 'rolled_back', ${nowIso}, ${nowIso}, ${encodeUnknownJsonString({ id: hiddenRunId, threadId, ordinal: 1001, providerInstanceId, modelSelection, providerThreadId: null, userMessageId: "message:bounded-sql-history:hidden-suffix", rootNodeId: "node:bounded-sql-history:hidden-suffix", activeAttemptId: null, status: "rolled_back", requestedAt: nowIso, startedAt: nowIso, completedAt: nowIso, checkpointId: null, contextHandoffId: null, })} ) `; for (let ordinal = 1_001; ordinal <= 1_100; ordinal += 1) { const id = `turn-item:bounded-sql-history:hidden:${ordinal}`; yield* sql` INSERT INTO orchestration_v2_projection_turn_items ( turn_item_id, thread_id, run_id, node_id, provider_thread_id, provider_turn_id, parent_item_id, ordinal, type, status, updated_at, payload_json ) VALUES ( ${id}, ${threadId}, ${hiddenRunId}, NULL, NULL, NULL, NULL, ${ordinal}, 'command_execution', 'completed', ${nowIso}, ${encodeUnknownJsonString({ id, threadId, runId: hiddenRunId, nodeId: null, providerThreadId: null, providerTurnId: null, nativeItemRef: null, parentItemId: null, ordinal, status: "completed", title: "rolled back", input: "echo hidden", output: "hidden", exitCode: 0, startedAt: nowIso, completedAt: nowIso, updatedAt: nowIso, type: "command_execution", })} ) `; } const hiddenSuffixSnapshot = yield* projectionStore.getThreadSnapshotWindow(threadId, { rowLimit: sqlPageLimit, }); const hiddenSuffixPage = buildBoundedThreadProjection({ projection: hiddenSuffixSnapshot.projection, snapshotSequence: hiddenSuffixSnapshot.snapshotSequence, }); assert.lengthOf(hiddenSuffixPage.projection.visibleTurnItems, 75); assert.strictEqual(hiddenSuffixPage.latestLocalTurnOrdinal, 1_100); assert.isTrue(hiddenSuffixPage.hasMoreHistory); assert.isFalse( hiddenSuffixPage.projection.visibleTurnItems.some((row) => String(row.sourceItemId).includes(":hidden:"), ), ); const hiddenSuffixCursor = hiddenSuffixPage.historyCursor; assert.isNotNull(hiddenSuffixCursor); const hiddenSuffixAnchor = TurnItemId.make(decodeThreadHistoryCursor(hiddenSuffixCursor!).si); const hiddenSuffixOlderSnapshot = yield* projectionStore.getThreadSnapshotWindow(threadId, { rowLimit: sqlPageLimit, anchorItemId: hiddenSuffixAnchor, }); const hiddenSuffixOlderPage = selectHistoryPageFromCursor({ items: hiddenSuffixOlderSnapshot.projection.visibleTurnItems, cursor: hiddenSuffixCursor!, snapshotSequence: hiddenSuffixOlderSnapshot.snapshotSequence, }); assert.lengthOf(hiddenSuffixOlderPage.items, 75); assert.isTrue(hiddenSuffixOlderPage.hasMoreHistory); const cancelledRunId = RunId.make("run:bounded-sql-history:cancelled-suffix"); yield* sql` INSERT INTO orchestration_v2_projection_runs ( run_id, thread_id, ordinal, provider, provider_thread_id, status, requested_at, completed_at, payload_json ) VALUES ( ${cancelledRunId}, ${threadId}, 1002, 'codex', NULL, 'cancelled', ${nowIso}, ${nowIso}, ${encodeUnknownJsonString({ id: cancelledRunId, threadId, ordinal: 1002, providerInstanceId, modelSelection, providerThreadId: null, userMessageId: "message:bounded-sql-history:cancelled-suffix", rootNodeId: "node:bounded-sql-history:cancelled-suffix", activeAttemptId: null, status: "cancelled", requestedAt: nowIso, startedAt: nowIso, completedAt: nowIso, checkpointId: null, contextHandoffId: null, })} ) `; for (let ordinal = 1_101; ordinal <= 1_200; ordinal += 1) { const id = `turn-item:bounded-sql-history:cancelled:${ordinal}`; yield* sql` INSERT INTO orchestration_v2_projection_turn_items ( turn_item_id, thread_id, run_id, node_id, provider_thread_id, provider_turn_id, parent_item_id, ordinal, type, status, updated_at, payload_json ) VALUES ( ${id}, ${threadId}, ${cancelledRunId}, NULL, NULL, NULL, NULL, ${ordinal}, 'user_message', 'completed', ${nowIso}, ${encodeUnknownJsonString({ createdBy: "user", creationSource: "web", id, threadId, runId: cancelledRunId, nodeId: null, providerThreadId: null, providerTurnId: null, nativeItemRef: null, parentItemId: null, ordinal, status: "completed", title: "cancelled queued message", startedAt: nowIso, completedAt: nowIso, updatedAt: nowIso, type: "user_message", messageId: `message:bounded-sql-history:cancelled:${ordinal}`, inputIntent: "queued_turn", text: "cancelled", attachments: [], })} ) `; } const runlessQueuedId = "turn-item:bounded-sql-history:runless-queued"; yield* sql` INSERT INTO orchestration_v2_projection_turn_items ( turn_item_id, thread_id, run_id, node_id, provider_thread_id, provider_turn_id, parent_item_id, ordinal, type, status, updated_at, payload_json ) VALUES ( ${runlessQueuedId}, ${threadId}, NULL, NULL, NULL, NULL, NULL, 1201, 'user_message', 'completed', ${nowIso}, ${encodeUnknownJsonString({ createdBy: "user", creationSource: "web", id: runlessQueuedId, threadId, runId: null, nodeId: null, providerThreadId: null, providerTurnId: null, nativeItemRef: null, parentItemId: null, ordinal: 1201, status: "completed", title: "runless queued message", startedAt: nowIso, completedAt: nowIso, updatedAt: nowIso, type: "user_message", messageId: "message:bounded-sql-history:runless-queued", inputIntent: "queued_turn", text: "still visible", attachments: [], })} ) `; const laterCancelledId = "turn-item:bounded-sql-history:cancelled:1202"; yield* sql` INSERT INTO orchestration_v2_projection_turn_items ( turn_item_id, thread_id, run_id, node_id, provider_thread_id, provider_turn_id, parent_item_id, ordinal, type, status, updated_at, payload_json ) VALUES ( ${laterCancelledId}, ${threadId}, ${cancelledRunId}, NULL, NULL, NULL, NULL, 1202, 'user_message', 'completed', ${nowIso}, ${encodeUnknownJsonString({ createdBy: "user", creationSource: "web", id: laterCancelledId, threadId, runId: cancelledRunId, nodeId: null, providerThreadId: null, providerTurnId: null, nativeItemRef: null, parentItemId: null, ordinal: 1202, status: "completed", title: "later cancelled queued message", startedAt: nowIso, completedAt: nowIso, updatedAt: nowIso, type: "user_message", messageId: "message:bounded-sql-history:cancelled:1202", inputIntent: "queued_turn", text: "cancelled", attachments: [], })} ) `; const cancelledSuffixSnapshot = yield* projectionStore.getThreadSnapshotWindow(threadId, { rowLimit: sqlPageLimit, }); const cancelledSuffixPage = buildBoundedThreadProjection({ projection: cancelledSuffixSnapshot.projection, snapshotSequence: cancelledSuffixSnapshot.snapshotSequence, }); assert.strictEqual(cancelledSuffixPage.latestLocalTurnOrdinal, 1_202); assert.lengthOf(cancelledSuffixPage.projection.visibleTurnItems, 75); assert.isFalse( cancelledSuffixPage.projection.visibleTurnItems.some((row) => String(row.sourceItemId).includes(":cancelled:"), ), ); assert.isTrue( cancelledSuffixPage.projection.visibleTurnItems.some( (row) => row.sourceItemId === runlessQueuedId, ), ); const interruptRunId = RunId.make("run:bounded-sql-history:interrupt"); const interruptNodeId = NodeId.make("node:bounded-sql-history:interrupt"); const interruptRequestId = TurnItemId.make("turn-item:bounded-sql-history:interrupt-request"); const interruptResultId = TurnItemId.make("turn-item:bounded-sql-history:interrupt-result"); yield* sql` INSERT INTO orchestration_v2_projection_runs ( run_id, thread_id, ordinal, provider, provider_thread_id, status, requested_at, completed_at, payload_json ) VALUES ( ${interruptRunId}, ${threadId}, 1003, 'codex', 'provider-thread:interrupt', 'completed', ${nowIso}, ${nowIso}, ${encodeUnknownJsonString({ id: interruptRunId, threadId, ordinal: 1003, providerInstanceId, modelSelection, providerThreadId: "provider-thread:interrupt", userMessageId: "message:interrupt", rootNodeId: interruptNodeId, activeAttemptId: "attempt:bounded-sql-history:interrupt", status: "completed", requestedAt: nowIso, startedAt: nowIso, completedAt: nowIso, checkpointId: null, contextHandoffId: null, })} ) `; yield* sql` INSERT INTO orchestration_v2_projection_run_attempts ( attempt_id, thread_id, run_id, attempt_ordinal, root_node_id, provider, provider_instance_id, provider_thread_id, provider_turn_id, status, payload_json ) VALUES ( 'attempt:bounded-sql-history:interrupt', ${threadId}, ${interruptRunId}, 1, ${interruptNodeId}, 'codex', ${providerInstanceId}, 'provider-thread:interrupt', NULL, 'superseded', ${encodeUnknownJsonString({ id: "attempt:bounded-sql-history:interrupt", runId: interruptRunId, attemptOrdinal: 1, rootNodeId: interruptNodeId, providerInstanceId, providerThreadId: "provider-thread:interrupt", providerTurnId: null, reason: "initial", status: "superseded", startedAt: nowIso, completedAt: nowIso, })} ) `; const insertInterruptItem = (input: { id: TurnItemId; ordinal: number; type: "run_interrupt_request" | "run_interrupt_result"; }) => sql` INSERT INTO orchestration_v2_projection_turn_items ( turn_item_id, thread_id, run_id, node_id, provider_thread_id, provider_turn_id, parent_item_id, ordinal, type, status, updated_at, payload_json ) VALUES ( ${input.id}, ${threadId}, ${interruptRunId}, ${interruptNodeId}, NULL, NULL, NULL, ${input.ordinal}, ${input.type}, 'completed', ${nowIso}, ${encodeUnknownJsonString({ id: input.id, threadId, runId: interruptRunId, nodeId: interruptNodeId, providerThreadId: null, providerTurnId: null, nativeItemRef: null, parentItemId: null, ordinal: input.ordinal, status: "completed", title: input.type, message: input.type === "run_interrupt_request" ? "Stopping" : "Stopped", startedAt: nowIso, completedAt: nowIso, updatedAt: nowIso, type: input.type, })} ) `; yield* insertInterruptItem({ id: interruptRequestId, ordinal: 1_201, type: "run_interrupt_request", }); for (let ordinal = 1_202; ordinal <= 1_281; ordinal += 1) { const id = `turn-item:bounded-sql-history:interrupt-filler:${ordinal}`; yield* sql` INSERT INTO orchestration_v2_projection_turn_items ( turn_item_id, thread_id, run_id, node_id, provider_thread_id, provider_turn_id, parent_item_id, ordinal, type, status, updated_at, payload_json ) VALUES ( ${id}, ${threadId}, NULL, NULL, NULL, NULL, NULL, ${ordinal}, 'command_execution', 'completed', ${nowIso}, ${encodeUnknownJsonString({ id, threadId, runId: null, nodeId: null, providerThreadId: null, providerTurnId: null, nativeItemRef: null, parentItemId: null, ordinal, status: "completed", title: "filler", input: "echo filler", output: "ok", exitCode: 0, startedAt: nowIso, completedAt: nowIso, updatedAt: nowIso, type: "command_execution", })} ) `; } yield* insertInterruptItem({ id: interruptResultId, ordinal: 1_282, type: "run_interrupt_result", }); const interruptSnapshot = yield* projectionStore.getThreadSnapshotWindow(threadId, { rowLimit: sqlPageLimit, }); assert.isTrue( interruptSnapshot.projection.turnItems.some((item) => item.id === interruptRequestId), ); assert.isTrue( interruptSnapshot.projection.visibleTurnItems.some( (row) => row.sourceItemId === interruptResultId, ), ); }), ); it.effect("scopes actionable provider state to the requested bounded thread", () => Effect.gen(function* () { const projectionStore = yield* ProjectionStoreV2; const now = yield* DateTime.now; const projectId = ProjectId.make("project:bounded-provider-scope"); const targetThreadId = ThreadId.make("thread:bounded-provider-scope:target"); const unrelatedThreadId = ThreadId.make("thread:bounded-provider-scope:unrelated"); const makeThread = (threadId: ThreadId) => ({ createdBy: "user" as const, creationSource: "web" as const, id: threadId, projectId, title: String(threadId), providerInstanceId, modelSelection, runtimeMode: "full-access" as const, interactionMode: "default" as const, branch: null, worktreePath: null, activeProviderThreadId: null, lineage: { parentThreadId: null, relationshipToParent: null, rootThreadId: threadId }, forkedFrom: null, createdAt: now, updatedAt: now, archivedAt: null, settledOverride: null, settledAt: null, lastVisitedAt: null, deletedAt: null, }); for (const threadId of [targetThreadId, unrelatedThreadId]) { yield* projectionStore.apply({ id: EventId.make(`event:bounded-provider-scope:thread:${threadId}`), type: "thread.created", threadId, occurredAt: now, payload: makeThread(threadId), }); const sessionId = ProviderSessionId.make(`provider-session:${threadId}`); const providerThreadId = ProviderThreadId.make(`provider-thread:${threadId}`); yield* projectionStore.apply({ id: EventId.make(`event:bounded-provider-scope:session:${threadId}`), type: "provider-session.attached", threadId, driver, occurredAt: now, payload: { id: sessionId, driver, providerInstanceId, status: "running", cwd: "/workspace", model: modelSelection.model, capabilities: CodexProviderCapabilitiesV2, createdAt: now, updatedAt: now, lastError: null, }, }); yield* projectionStore.apply({ id: EventId.make(`event:bounded-provider-scope:provider-thread:${threadId}`), type: "provider-thread.updated", threadId, driver, occurredAt: now, payload: { id: providerThreadId, driver, providerInstanceId, providerSessionId: sessionId, appThreadId: threadId, ownerNodeId: null, nativeThreadRef: null, nativeConversationHeadRef: null, status: "active", firstRunOrdinal: null, lastRunOrdinal: null, handoffIds: [], forkedFrom: null, createdAt: now, updatedAt: now, }, }); } const snapshot = yield* projectionStore.getThreadSnapshotWindow(targetThreadId, { rowLimit: 10, }); assert.deepEqual( snapshot.projection.providerSessions.map((session) => session.id), [ProviderSessionId.make(`provider-session:${targetThreadId}`)], ); assert.deepEqual( snapshot.projection.providerThreads.map((thread) => thread.id), [ProviderThreadId.make(`provider-thread:${targetThreadId}`)], ); }), ); it.effect("does not treat visited or marked-unread state as thread activity", () => Effect.gen(function* () { const projectionStore = yield* ProjectionStoreV2; const createdAt = yield* DateTime.now; const visitedOccurredAt = DateTime.add(createdAt, { seconds: 1 }); const markedUnreadOccurredAt = DateTime.add(createdAt, { seconds: 2 }); const threadId = ThreadId.make("thread:projection-read-state"); const projectId = ProjectId.make("project:projection-read-state"); const thread = { createdBy: "user" as const, creationSource: "web" as const, id: threadId, projectId, title: "Projection read state", providerInstanceId, modelSelection, runtimeMode: "full-access" as const, interactionMode: "default" as const, branch: null, worktreePath: null, activeProviderThreadId: null, lineage: { parentThreadId: null, relationshipToParent: null, rootThreadId: threadId, }, forkedFrom: null, createdAt, updatedAt: createdAt, archivedAt: null, settledOverride: null, settledAt: null, lastVisitedAt: null, deletedAt: null, }; yield* projectionStore.apply({ id: EventId.make("event:projection-read-state:created"), type: "thread.created", threadId, occurredAt: createdAt, payload: thread, }); yield* projectionStore.apply({ id: EventId.make("event:projection-read-state:visited"), type: "thread.visited", threadId, occurredAt: visitedOccurredAt, payload: { ...thread, lastVisitedAt: createdAt }, }); const visited = yield* projectionStore.getThreadProjection(threadId); assert.deepEqual(visited.thread.lastVisitedAt, createdAt); assert.deepEqual(visited.thread.updatedAt, createdAt); yield* projectionStore.apply({ id: EventId.make("event:projection-read-state:marked-unread"), type: "thread.marked-unread", threadId, occurredAt: markedUnreadOccurredAt, payload: thread, }); const markedUnread = yield* projectionStore.getThreadProjection(threadId); assert.isNull(markedUnread.thread.lastVisitedAt); assert.deepEqual(markedUnread.thread.updatedAt, createdAt); }), ); it.effect("preserves delegated completion ownership across stale run and task updates", () => Effect.gen(function* () { const projectionStore = yield* ProjectionStoreV2; const now = yield* DateTime.now; const later = DateTime.add(now, { seconds: 1 }); const threadId = ThreadId.make("thread:projection-delegated-completion"); const projectId = ProjectId.make("project:projection-delegated-completion"); const runId = RunId.make("run:projection-delegated-completion"); const rootNodeId = NodeId.make("node:projection-delegated-completion-root"); const taskId = NodeId.make("node:projection-delegated-completion-task"); const thread = { createdBy: "user" as const, creationSource: "web" as const, id: threadId, projectId, title: "Delegated completion projection", providerInstanceId, modelSelection, runtimeMode: "full-access" as const, interactionMode: "default" as const, branch: null, worktreePath: null, activeProviderThreadId: null, lineage: { parentThreadId: null, relationshipToParent: null, rootThreadId: threadId, }, forkedFrom: null, createdAt: now, updatedAt: now, archivedAt: null, settledOverride: null, settledAt: null, lastVisitedAt: null, deletedAt: null, }; const run = { id: runId, threadId, ordinal: 1, providerInstanceId, modelSelection, providerThreadId: null, userMessageId: MessageId.make("message:projection-delegated-completion"), rootNodeId, activeAttemptId: null, status: "running" as const, requestedAt: now, startedAt: now, completedAt: null, checkpointId: null, contextHandoffId: null, delegatedCompletion: { disposition: "stopped" as const, nextGeneration: 2, delivery: null, }, }; const task = { id: taskId, threadId, runId, parentNodeId: rootNodeId, origin: "app_owned" as const, createdBy: "agent" as const, driver, providerInstanceId, providerThreadId: null, childThreadId: null, nativeTaskRef: null, prompt: "Inspect the stop barrier.", title: null, model: null, completionWake: "always" as const, completionDelivery: { state: "disposed" as const, observedByRunId: null, }, status: "running" as const, result: null, startedAt: now, completedAt: null, updatedAt: now, }; yield* projectionStore.apply({ id: EventId.make("event:projection-delegated-completion:thread"), type: "thread.created", threadId, occurredAt: now, payload: thread, }); yield* projectionStore.apply({ id: EventId.make("event:projection-delegated-completion:run"), type: "run.updated", threadId, runId, nodeId: rootNodeId, providerInstanceId, occurredAt: now, payload: run, }); yield* projectionStore.apply({ id: EventId.make("event:projection-delegated-completion:task"), type: "subagent.updated", threadId, runId, nodeId: taskId, driver, providerInstanceId, occurredAt: now, payload: task, }); const { delegatedCompletion: _delegatedCompletion, ...staleRun } = run; const { completionDelivery: _completionDelivery, ...staleTask } = task; yield* projectionStore.apply({ id: EventId.make("event:projection-delegated-completion:stale-run"), type: "run.updated", threadId, runId, nodeId: rootNodeId, providerInstanceId, occurredAt: later, payload: { ...staleRun, status: "interrupted", completedAt: later }, }); yield* projectionStore.apply({ id: EventId.make("event:projection-delegated-completion:stale-task"), type: "subagent.updated", threadId, runId, nodeId: taskId, driver, providerInstanceId, occurredAt: later, payload: { ...staleTask, status: "interrupted", completedAt: later, updatedAt: later, }, }); const projection = yield* projectionStore.getThreadProjection(threadId); assert.deepEqual(projection.runs[0]?.delegatedCompletion, run.delegatedCompletion); assert.deepEqual(projection.subagents[0]?.completionDelivery, task.completionDelivery); }), ); it.effect("only exposes interruptible runs through the shell activeRunId", () => Effect.gen(function* () { const projectionStore = yield* ProjectionStoreV2; const now = yield* DateTime.now; const threadId = ThreadId.make("thread:projection-shell-interruptible"); const projectId = ProjectId.make("project:projection-shell-interruptible"); const runId = RunId.make("run:projection-shell-interruptible"); const rootNodeId = NodeId.make("node:projection-shell-interruptible"); const run = { id: runId, threadId, ordinal: 1, providerInstanceId, modelSelection, providerThreadId: null, userMessageId: MessageId.make("message:projection-shell-interruptible"), rootNodeId, activeAttemptId: null, status: "running" as const, requestedAt: now, startedAt: now, completedAt: null, checkpointId: null, contextHandoffId: null, }; yield* projectionStore.apply({ id: EventId.make("event:projection-shell-interruptible:thread"), type: "thread.created", threadId, occurredAt: now, payload: { createdBy: "user", creationSource: "web", id: threadId, projectId, title: "Interruptible shell run", providerInstanceId, modelSelection, runtimeMode: "full-access", interactionMode: "default", branch: null, worktreePath: null, activeProviderThreadId: null, lineage: { parentThreadId: null, relationshipToParent: null, rootThreadId: threadId, }, forkedFrom: null, createdAt: now, updatedAt: now, archivedAt: null, settledOverride: null, settledAt: null, lastVisitedAt: null, deletedAt: null, }, }); yield* projectionStore.apply({ id: EventId.make("event:projection-shell-interruptible:running"), type: "run.created", threadId, runId, nodeId: rootNodeId, driver, occurredAt: now, payload: run, }); let shell = (yield* projectionStore.getShellSnapshot()).threads.find( (thread) => thread.id === threadId, ); assert.equal(shell?.status, "running"); assert.equal(shell?.activeRunId, runId); assert.equal( shell?.latestRunRequestedAt && DateTime.toEpochMillis(shell.latestRunRequestedAt), DateTime.toEpochMillis(now), ); assert.equal( shell?.latestRunStartedAt && DateTime.toEpochMillis(shell.latestRunStartedAt), DateTime.toEpochMillis(now), ); assert.isNull(shell?.latestRunCompletedAt); yield* projectionStore.apply({ id: EventId.make("event:projection-shell-interruptible:waiting"), type: "run.updated", threadId, runId, nodeId: rootNodeId, driver, occurredAt: now, payload: { ...run, status: "waiting" }, }); shell = (yield* projectionStore.getShellSnapshot()).threads.find( (thread) => thread.id === threadId, ); assert.equal(shell?.status, "waiting"); assert.isNull(shell?.activeRunId); }), ); it.effect("projects one shared provider session into multiple thread bindings", () => Effect.gen(function* () { const projectionStore = yield* ProjectionStoreV2; const now = yield* DateTime.now; const projectId = ProjectId.make("project:projection-shared-provider-session"); const firstThreadId = ThreadId.make("thread:projection-shared-provider-session:first"); const secondThreadId = ThreadId.make("thread:projection-shared-provider-session:second"); const providerSessionId = ProviderSessionId.make( "provider-session:projection-shared-provider-session", ); const makeThread = (threadId: ThreadId) => ({ createdBy: "user" as const, creationSource: "web" as const, id: threadId, projectId, title: "Shared provider session", providerInstanceId, modelSelection, runtimeMode: "full-access" as const, interactionMode: "default" as const, branch: null, worktreePath: null, activeProviderThreadId: null, lineage: { parentThreadId: null, relationshipToParent: null, rootThreadId: threadId, }, forkedFrom: null, createdAt: now, updatedAt: now, archivedAt: null, settledOverride: null, settledAt: null, lastVisitedAt: null, deletedAt: null, }); const session = { id: providerSessionId, driver, providerInstanceId, status: "error" as const, cwd: "/workspace", model: modelSelection.model, capabilities: CodexProviderCapabilitiesV2, createdAt: now, updatedAt: now, lastError: "provider process exited", }; yield* projectionStore.apply({ id: EventId.make("event:projection-shared-provider-session:first-thread"), type: "thread.created", threadId: firstThreadId, occurredAt: now, payload: makeThread(firstThreadId), }); yield* projectionStore.apply({ id: EventId.make("event:projection-shared-provider-session:second-thread"), type: "thread.created", threadId: secondThreadId, occurredAt: now, payload: makeThread(secondThreadId), }); for (const [threadId, suffix] of [ [firstThreadId, "first"], [secondThreadId, "second"], ] as const) { yield* projectionStore.apply({ id: EventId.make(`event:projection-shared-provider-session:${suffix}-binding`), type: "provider-session.attached", threadId, driver, providerInstanceId, occurredAt: now, payload: session, }); } assert.deepEqual( (yield* projectionStore.getThreadProjection(firstThreadId)).providerSessions.map( (value) => value.id, ), [providerSessionId], ); assert.deepEqual( (yield* projectionStore.getThreadProjection(secondThreadId)).providerSessions.map( (value) => value.id, ), [providerSessionId], ); assert.deepEqual( (yield* projectionStore.getShellSnapshot()).threads .filter((thread) => thread.id === firstThreadId || thread.id === secondThreadId) .map((thread) => ({ id: thread.id, lastError: thread.lastError, })), [ { id: firstThreadId, lastError: "provider process exited" }, { id: secondThreadId, lastError: "provider process exited" }, ], ); yield* projectionStore.apply({ id: EventId.make("event:projection-shared-provider-session:first-detached"), type: "provider-session.detached", threadId: firstThreadId, driver, providerInstanceId, occurredAt: now, payload: { providerSessionId, detachedAt: now }, }); assert.lengthOf( (yield* projectionStore.getThreadProjection(firstThreadId)).providerSessions, 0, ); assert.lengthOf( (yield* projectionStore.getThreadProjection(secondThreadId)).providerSessions, 1, ); }), ); it.effect( "reads checkpoint context without decoding transcript or checkpoint file payloads", () => Effect.gen(function* () { const projectionStore = yield* ProjectionStoreV2; const sql = yield* SqlClient.SqlClient; const now = yield* DateTime.now; const threadId = ThreadId.make("thread:checkpoint-context"); const runId = RunId.make("run:checkpoint-context"); const nodeId = NodeId.make("node:checkpoint-context"); const scopeId = CheckpointScopeId.make("scope:checkpoint-context"); const checkpointId = CheckpointId.make("checkpoint:checkpoint-context"); const ref = CheckpointRef.make("refs/t3/checkpoint-context/1"); yield* projectionStore.apply({ id: EventId.make("event:checkpoint-context:thread"), type: "thread.created", threadId, occurredAt: now, payload: { createdBy: "user", creationSource: "web", id: threadId, projectId: ProjectId.make("project:checkpoint-context"), title: "Checkpoint context", providerInstanceId, modelSelection, runtimeMode: "full-access", interactionMode: "default", branch: "feature", worktreePath: "/repo/worktree", activeProviderThreadId: null, lineage: { parentThreadId: null, relationshipToParent: null, rootThreadId: threadId }, forkedFrom: null, createdAt: now, updatedAt: now, archivedAt: null, settledOverride: null, settledAt: null, lastVisitedAt: null, deletedAt: null, }, }); yield* projectionStore.apply({ id: EventId.make("event:checkpoint-context:run"), type: "run.created", threadId, occurredAt: now, payload: { id: runId, threadId, ordinal: 1, providerInstanceId, modelSelection, providerThreadId: null, userMessageId: MessageId.make("message:checkpoint-context"), rootNodeId: nodeId, activeAttemptId: null, status: "completed", requestedAt: now, startedAt: now, completedAt: now, checkpointId, contextHandoffId: null, }, }); yield* projectionStore.apply({ id: EventId.make("event:checkpoint-context:scope"), type: "checkpoint-scope.created", threadId, occurredAt: now, payload: { id: scopeId, threadId, runId, nodeId, parentScopeId: null, providerThreadId: null, kind: "root_run", ordinalWithinParent: 0, advancesAppRunCount: true, cwd: "/repo/worktree", createdAt: now, }, }); yield* projectionStore.apply({ id: EventId.make("event:checkpoint-context:checkpoint"), type: "checkpoint.captured", threadId, occurredAt: now, payload: { id: checkpointId, threadId, scopeId, runId, nodeId, parentCheckpointId: null, ordinalWithinScope: 1, appRunOrdinal: 1, ref, status: "ready", files: [], capturedAt: now, }, }); // Old transcript shapes must not make a metadata-only diff unreadable. yield* sql` INSERT INTO orchestration_v2_projection_turn_items ( turn_item_id, thread_id, run_id, node_id, provider_thread_id, provider_turn_id, parent_item_id, ordinal, type, status, updated_at, payload_json ) VALUES ( 'turn-item:checkpoint-context:obsolete', ${threadId}, ${runId}, ${nodeId}, NULL, NULL, NULL, 1, 'assistant_message', 'completed', ${DateTime.formatIso(now)}, ${encodeUnknownJsonString({ obsolete: "transcript shape" })} ) `; assert.strictEqual( (yield* Effect.exit(projectionStore.getThreadProjection(threadId)))._tag, "Failure", ); yield* sql` UPDATE orchestration_v2_projection_checkpoints SET payload_json = json_set(payload_json, '$.files', 'obsolete file summary') WHERE checkpoint_id = ${checkpointId} `; assert.deepEqual(yield* projectionStore.getCheckpointContext(threadId), { runs: [{ id: runId, ordinal: 1, status: "completed" }], checkpointScopes: [{ id: scopeId, runId, kind: "root_run", cwd: "/repo/worktree" }], checkpoints: [{ scopeId, runId, appRunOrdinal: 1, status: "ready", ref }], }); const missing = yield* projectionStore .getCheckpointContext(ThreadId.make("thread:checkpoint-context:missing")) .pipe(Effect.flip); assert.instanceOf(missing, ProjectionStoreThreadNotFoundError); }), ); it.effect("builds shell snapshots without decoding full turn item payloads", () => Effect.gen(function* () { const projectionStore = yield* ProjectionStoreV2; const sql = yield* SqlClient.SqlClient; const now = yield* DateTime.now; const nowIso = DateTime.formatIso(now); const threadId = ThreadId.make("thread:projection-shell-stale-item"); const projectId = ProjectId.make("project:projection-shell"); yield* projectionStore.apply({ id: EventId.make("event:projection-shell-thread-created"), type: "thread.created", threadId, occurredAt: now, payload: { createdBy: "user", creationSource: "web", id: threadId, projectId, title: "Projection shell", providerInstanceId, modelSelection: modelSelection, runtimeMode: "full-access", interactionMode: "default", branch: null, worktreePath: null, activeProviderThreadId: null, lineage: { parentThreadId: null, relationshipToParent: null, rootThreadId: threadId, }, forkedFrom: null, createdAt: now, updatedAt: now, archivedAt: null, settledOverride: null, settledAt: null, lastVisitedAt: null, deletedAt: null, }, }); yield* sql` INSERT INTO orchestration_v2_projection_turn_items ( turn_item_id, thread_id, run_id, node_id, provider_thread_id, provider_turn_id, parent_item_id, ordinal, type, status, updated_at, payload_json ) VALUES ( ${"turn-item:stale-user-message"}, ${threadId}, ${null}, ${null}, ${null}, ${null}, ${null}, ${0}, ${"user_message"}, ${"completed"}, ${nowIso}, ${encodeUnknownJsonString({ id: "turn-item:stale-user-message", threadId, runId: null, nodeId: null, providerThreadId: null, providerTurnId: null, nativeItemRef: null, parentItemId: null, ordinal: 0, status: "completed", title: null, startedAt: nowIso, completedAt: nowIso, updatedAt: nowIso, type: "user_message", messageId: "message:stale-user-message", text: "stale user message", attachments: [], })} ) `; const shell = yield* projectionStore.getShellSnapshot(); const fullProjectionExit = yield* Effect.exit(projectionStore.getThreadProjection(threadId)); assert.deepEqual( shell.threads .filter((thread) => thread.id === threadId) .map((thread) => ({ id: thread.id, itemCount: thread.itemCount, visibleItemCount: thread.visibleItemCount, status: thread.status, })), [ { id: threadId, itemCount: 1, visibleItemCount: 1, status: "idle", }, ], ); assert.equal(fullProjectionExit._tag, "Failure"); }), ); it.effect("counts imported runless history inherited by fork shells", () => Effect.gen(function* () { const projectionStore = yield* ProjectionStoreV2; const now = yield* DateTime.now; const projectId = ProjectId.make("project:projection-imported-fork-shell"); const sourceThreadId = ThreadId.make("thread:projection-imported-fork-shell:source"); const targetThreadId = ThreadId.make("thread:projection-imported-fork-shell:target"); const sourceRunId = RunId.make("run:projection-imported-fork-shell:source"); const rootNodeId = NodeId.make("node:projection-imported-fork-shell:source"); yield* projectionStore.apply({ id: EventId.make("event:projection-imported-fork-shell:source-thread"), type: "thread.created", threadId: sourceThreadId, occurredAt: now, payload: { createdBy: "system", creationSource: "server", id: sourceThreadId, projectId, title: "Imported fork source", providerInstanceId, modelSelection, runtimeMode: "full-access", interactionMode: "default", branch: null, worktreePath: null, activeProviderThreadId: null, historyOrigin: "v1_import", lineage: { parentThreadId: null, relationshipToParent: null, rootThreadId: sourceThreadId, }, forkedFrom: null, createdAt: now, updatedAt: now, archivedAt: null, settledOverride: null, settledAt: null, lastVisitedAt: null, deletedAt: null, }, }); yield* projectionStore.apply({ id: EventId.make("event:projection-imported-fork-shell:target-thread"), type: "thread.created", threadId: targetThreadId, occurredAt: now, payload: { createdBy: "user", creationSource: "web", id: targetThreadId, projectId, title: "Imported fork target", providerInstanceId, modelSelection, runtimeMode: "full-access", interactionMode: "default", branch: null, worktreePath: null, activeProviderThreadId: null, lineage: { parentThreadId: sourceThreadId, relationshipToParent: "fork", rootThreadId: sourceThreadId, }, forkedFrom: { type: "run", threadId: sourceThreadId, runId: sourceRunId, }, createdAt: now, updatedAt: now, archivedAt: null, settledOverride: null, settledAt: null, lastVisitedAt: null, deletedAt: null, }, }); yield* projectionStore.apply({ id: EventId.make("event:projection-imported-fork-shell:source-run"), type: "run.created", threadId: sourceThreadId, runId: sourceRunId, nodeId: rootNodeId, driver, occurredAt: now, payload: { id: sourceRunId, threadId: sourceThreadId, ordinal: 1, providerInstanceId, modelSelection, providerThreadId: null, userMessageId: MessageId.make("message:projection-imported-fork-shell:run"), rootNodeId, activeAttemptId: null, status: "completed", requestedAt: now, startedAt: now, completedAt: now, checkpointId: null, contextHandoffId: null, }, }); const applyAssistantItem = (suffix: string, runId: RunId | null, ordinal: number) => projectionStore.apply({ id: EventId.make(`event:projection-imported-fork-shell:item:${suffix}`), type: "turn-item.updated", threadId: sourceThreadId, ...(runId === null ? {} : { runId }), occurredAt: now, payload: { id: TurnItemId.make(`turn-item:projection-imported-fork-shell:${suffix}`), threadId: sourceThreadId, runId, nodeId: null, providerThreadId: null, providerTurnId: null, nativeItemRef: null, parentItemId: null, ordinal, status: "completed", title: null, startedAt: now, completedAt: now, updatedAt: now, type: "assistant_message", messageId: MessageId.make(`message:projection-imported-fork-shell:${suffix}`), text: suffix, streaming: false, }, }); yield* applyAssistantItem("imported-one", null, 1); yield* applyAssistantItem("imported-two", null, 2); yield* applyAssistantItem("native-run", sourceRunId, 3); const shell = yield* projectionStore.getShellSnapshot(); const targetShell = shell.threads.find((thread) => thread.id === targetThreadId); const targetProjection = yield* projectionStore.getThreadProjection(targetThreadId); assert.isDefined(targetShell); assert.equal(targetShell.itemCount, 0); assert.equal(targetShell.visibleItemCount, 4); assert.equal(targetProjection.visibleTurnItems.length, 4); }), ); it.effect("removes rolled back runs from the active visible projection", () => Effect.gen(function* () { const projectionStore = yield* ProjectionStoreV2; const now = yield* DateTime.now; const threadId = ThreadId.make("thread:projection-rollback-prune"); const projectId = ProjectId.make("project:projection-rollback-prune"); const runId = RunId.make("run:projection-rollback-prune"); const attemptId = RunAttemptId.make("attempt:projection-rollback-prune"); const rootNodeId = NodeId.make("node:projection-rollback-prune:root"); const assistantNodeId = NodeId.make("node:projection-rollback-prune:assistant"); const providerThreadId = ProviderThreadId.make("provider-thread:projection-rollback-prune"); const providerTurnId = ProviderTurnId.make("provider-turn:projection-rollback-prune"); const userMessageId = MessageId.make("message:projection-rollback-prune:user"); const assistantMessageId = MessageId.make("message:projection-rollback-prune:assistant"); const userTurnItemId = TurnItemId.make("turn-item:projection-rollback-prune:user"); const assistantTurnItemId = TurnItemId.make("turn-item:projection-rollback-prune:assistant"); const backgroundTurnItemId = TurnItemId.make( "turn-item:projection-rollback-prune:background", ); yield* projectionStore.apply({ id: EventId.make("event:projection-rollback-prune:thread-created"), type: "thread.created", threadId, occurredAt: now, payload: { createdBy: "user", creationSource: "web", id: threadId, projectId, title: "Projection rollback prune", providerInstanceId, modelSelection, runtimeMode: "full-access", interactionMode: "default", branch: null, worktreePath: null, activeProviderThreadId: providerThreadId, lineage: { parentThreadId: null, relationshipToParent: null, rootThreadId: threadId, }, forkedFrom: null, createdAt: now, updatedAt: now, archivedAt: null, settledOverride: null, settledAt: null, lastVisitedAt: null, deletedAt: null, }, }); yield* projectionStore.apply({ id: EventId.make("event:projection-rollback-prune:provider-thread"), type: "provider-thread.updated", threadId, driver, occurredAt: now, payload: { id: providerThreadId, driver, providerInstanceId, providerSessionId: null, appThreadId: threadId, ownerNodeId: null, nativeThreadRef: null, nativeConversationHeadRef: null, status: "active", firstRunOrdinal: 1, lastRunOrdinal: 1, handoffIds: [], forkedFrom: null, createdAt: now, updatedAt: now, }, }); yield* projectionStore.apply({ id: EventId.make("event:projection-rollback-prune:run-created"), type: "run.created", threadId, runId, nodeId: rootNodeId, driver, occurredAt: now, payload: { id: runId, threadId, ordinal: 1, providerInstanceId, modelSelection, providerThreadId, userMessageId, rootNodeId, activeAttemptId: attemptId, status: "completed", requestedAt: now, startedAt: now, completedAt: now, checkpointId: null, contextHandoffId: null, }, }); yield* projectionStore.apply({ id: EventId.make("event:projection-rollback-prune:attempt-created"), type: "run-attempt.created", threadId, runId, nodeId: rootNodeId, driver, occurredAt: now, payload: { id: attemptId, runId, attemptOrdinal: 1, rootNodeId, providerInstanceId, providerThreadId, providerTurnId, reason: "initial", status: "completed", startedAt: now, completedAt: now, }, }); yield* projectionStore.apply({ id: EventId.make("event:projection-rollback-prune:root-node"), type: "node.updated", threadId, runId, nodeId: rootNodeId, driver, occurredAt: now, payload: { id: rootNodeId, threadId, runId, parentNodeId: null, rootNodeId, kind: "root_turn", status: "completed", countsForRun: true, providerThreadId, providerTurnId: null, nativeItemRef: null, runtimeRequestId: null, checkpointScopeId: null, startedAt: now, completedAt: now, }, }); yield* projectionStore.apply({ id: EventId.make("event:projection-rollback-prune:assistant-node"), type: "node.updated", threadId, runId, nodeId: assistantNodeId, driver, occurredAt: now, payload: { id: assistantNodeId, threadId, runId, parentNodeId: rootNodeId, rootNodeId, kind: "assistant_message", status: "completed", countsForRun: false, providerThreadId, providerTurnId, nativeItemRef: null, runtimeRequestId: null, checkpointScopeId: null, startedAt: now, completedAt: now, }, }); yield* projectionStore.apply({ id: EventId.make("event:projection-rollback-prune:provider-turn"), type: "provider-turn.updated", threadId, runId, nodeId: rootNodeId, driver, occurredAt: now, payload: { id: providerTurnId, providerThreadId, nodeId: rootNodeId, runAttemptId: attemptId, nativeTurnRef: null, ordinal: 1, status: "completed", startedAt: now, completedAt: now, }, }); yield* projectionStore.apply({ id: EventId.make("event:projection-rollback-prune:user-message"), type: "message.updated", threadId, runId, nodeId: rootNodeId, driver, occurredAt: now, payload: { createdBy: "user", creationSource: "web", id: userMessageId, threadId, runId, nodeId: rootNodeId, role: "user", text: "rolled back user", attachments: [], streaming: false, createdAt: now, updatedAt: now, }, }); yield* projectionStore.apply({ id: EventId.make("event:projection-rollback-prune:assistant-message"), type: "message.updated", threadId, runId, nodeId: assistantNodeId, driver, occurredAt: now, payload: { createdBy: "agent", creationSource: "provider", id: assistantMessageId, threadId, runId, nodeId: assistantNodeId, role: "assistant", text: "rolled back assistant", attachments: [], streaming: false, createdAt: now, updatedAt: now, }, }); yield* projectionStore.apply({ id: EventId.make("event:projection-rollback-prune:user-item"), type: "turn-item.updated", threadId, runId, nodeId: rootNodeId, driver, occurredAt: now, payload: { createdBy: "user", creationSource: "web", id: userTurnItemId, threadId, runId, nodeId: rootNodeId, providerThreadId, providerTurnId: null, nativeItemRef: null, parentItemId: null, ordinal: 100, status: "completed", title: null, startedAt: now, completedAt: now, updatedAt: now, type: "user_message", messageId: userMessageId, inputIntent: "turn_start", text: "rolled back user", attachments: [], }, }); yield* projectionStore.apply({ id: EventId.make("event:projection-rollback-prune:assistant-item"), type: "turn-item.updated", threadId, runId, nodeId: assistantNodeId, driver, occurredAt: now, payload: { id: assistantTurnItemId, threadId, runId, nodeId: assistantNodeId, providerThreadId, providerTurnId, nativeItemRef: null, parentItemId: null, ordinal: 101, status: "completed", title: null, startedAt: now, completedAt: now, updatedAt: now, type: "assistant_message", messageId: assistantMessageId, text: "rolled back assistant", streaming: false, }, }); yield* projectionStore.apply({ id: EventId.make("event:projection-rollback-prune:background-item"), type: "turn-item.updated", threadId, runId, nodeId: rootNodeId, driver, occurredAt: now, payload: { id: backgroundTurnItemId, threadId, runId, nodeId: rootNodeId, providerThreadId, providerTurnId: null, nativeItemRef: null, parentItemId: null, ordinal: 300, status: "running", title: "rolled back background command", startedAt: now, completedAt: null, updatedAt: now, type: "command_execution", input: "sleep 60", }, }); yield* projectionStore.apply({ id: EventId.make("event:projection-rollback-prune:run-rolled-back"), type: "run.updated", threadId, runId, nodeId: rootNodeId, driver, occurredAt: now, payload: { id: runId, threadId, ordinal: 1, providerInstanceId, modelSelection, providerThreadId, userMessageId, rootNodeId, activeAttemptId: attemptId, status: "rolled_back", requestedAt: now, startedAt: now, completedAt: now, checkpointId: null, contextHandoffId: null, }, }); yield* projectionStore.apply({ id: EventId.make("event:projection-rollback-prune:root-rolled-back"), type: "node.updated", threadId, runId, nodeId: rootNodeId, driver, occurredAt: now, payload: { id: rootNodeId, threadId, runId, parentNodeId: null, rootNodeId, kind: "root_turn", status: "rolled_back", countsForRun: true, providerThreadId, providerTurnId: null, nativeItemRef: null, runtimeRequestId: null, checkpointScopeId: null, startedAt: now, completedAt: now, }, }); const projection = yield* projectionStore.getThreadProjection(threadId); assert.deepEqual( projection.runs.map((run) => run.status), ["rolled_back"], ); assert.deepEqual( projection.nodes.map((node) => [node.id, node.status]), [ [assistantNodeId, "completed"], [rootNodeId, "rolled_back"], ], ); assert.lengthOf(projection.providerTurns, 1); assert.lengthOf(projection.messages, 2); assert.lengthOf(projection.turnItems, 3); assert.lengthOf(projection.visibleTurnItems, 0); // A rolled-back run's background item is abandoned, not pending. The // shell must not report it as Waiting, or the sidebar shows Waiting for // work nothing will ever finish. const shell = yield* projectionStore.getShellSnapshot(); const rolledBackShellThread = shell.threads.find((entry) => entry.id === threadId); assert.isDefined(rolledBackShellThread); assert.isNull(rolledBackShellThread.latestVisibleMessage); assert.deepEqual(rolledBackShellThread?.pendingBackgroundTasks ?? [], []); }), ); it.effect("keeps fork visible items stable after a source run is rolled back", () => Effect.gen(function* () { const projectionStore = yield* ProjectionStoreV2; const sql = yield* SqlClient.SqlClient; const now = yield* DateTime.now; const projectId = ProjectId.make("project:projection-fork-source-rollback"); const sourceThreadId = ThreadId.make("thread:projection-fork-source-rollback:source"); const targetThreadId = ThreadId.make("thread:projection-fork-source-rollback:target"); const sourceProviderThreadId = ProviderThreadId.make( "provider-thread:projection-fork-source-rollback:source", ); const targetProviderThreadId = ProviderThreadId.make( "provider-thread:projection-fork-source-rollback:target", ); const sourceRun1Id = RunId.make("run:projection-fork-source-rollback:source:1"); const sourceRun2Id = RunId.make("run:projection-fork-source-rollback:source:2"); const sourceRun3Id = RunId.make("run:projection-fork-source-rollback:source:3"); const sourceRun1NodeId = NodeId.make("node:projection-fork-source-rollback:source:1"); const sourceRun2NodeId = NodeId.make("node:projection-fork-source-rollback:source:2"); const sourceRun3NodeId = NodeId.make("node:projection-fork-source-rollback:source:3"); yield* projectionStore.apply({ id: EventId.make("event:projection-fork-source-rollback:source-thread"), type: "thread.created", threadId: sourceThreadId, occurredAt: now, payload: { createdBy: "user", creationSource: "web", id: sourceThreadId, projectId, title: "Projection fork source rollback source", providerInstanceId, modelSelection, runtimeMode: "full-access", interactionMode: "default", branch: null, worktreePath: null, activeProviderThreadId: sourceProviderThreadId, lineage: { parentThreadId: null, relationshipToParent: null, rootThreadId: sourceThreadId, }, forkedFrom: null, createdAt: now, updatedAt: now, archivedAt: null, settledOverride: null, settledAt: null, lastVisitedAt: null, deletedAt: null, }, }); yield* projectionStore.apply({ id: EventId.make("event:projection-fork-source-rollback:target-thread"), type: "thread.created", threadId: targetThreadId, occurredAt: now, payload: { createdBy: "user", creationSource: "web", id: targetThreadId, projectId, title: "Projection fork source rollback target", providerInstanceId, modelSelection, runtimeMode: "full-access", interactionMode: "default", branch: null, worktreePath: null, activeProviderThreadId: targetProviderThreadId, lineage: { parentThreadId: sourceThreadId, relationshipToParent: "fork", rootThreadId: sourceThreadId, }, forkedFrom: { type: "run", threadId: sourceThreadId, runId: sourceRun2Id, }, createdAt: now, updatedAt: now, archivedAt: null, settledOverride: null, settledAt: null, lastVisitedAt: null, deletedAt: null, }, }); for (const [ordinal, runId, nodeId, promptText, responseText] of [ [1, sourceRun1Id, sourceRun1NodeId, "source one", "one"], [2, sourceRun2Id, sourceRun2NodeId, "source two", "two"], ] as const) { yield* projectionStore.apply({ id: EventId.make(`event:projection-fork-source-rollback:run-${ordinal}`), type: "run.created", threadId: sourceThreadId, runId, nodeId, driver, occurredAt: now, payload: { id: runId, threadId: sourceThreadId, ordinal, providerInstanceId, modelSelection, providerThreadId: sourceProviderThreadId, userMessageId: MessageId.make( `message:projection-fork-source-rollback:user:${ordinal}`, ), rootNodeId: nodeId, activeAttemptId: null, status: "completed", requestedAt: now, startedAt: now, completedAt: now, checkpointId: null, contextHandoffId: null, }, }); yield* projectionStore.apply({ id: EventId.make(`event:projection-fork-source-rollback:user-item-${ordinal}`), type: "turn-item.updated", threadId: sourceThreadId, runId, nodeId, driver, occurredAt: now, payload: { createdBy: "user", creationSource: "web", id: TurnItemId.make(`turn-item:projection-fork-source-rollback:user:${ordinal}`), threadId: sourceThreadId, runId, nodeId, providerThreadId: sourceProviderThreadId, providerTurnId: null, nativeItemRef: null, parentItemId: null, ordinal: ordinal * 100, status: "completed", title: null, startedAt: now, completedAt: now, updatedAt: now, type: "user_message", messageId: MessageId.make(`message:projection-fork-source-rollback:user:${ordinal}`), inputIntent: "turn_start", text: promptText, attachments: [], }, }); yield* projectionStore.apply({ id: EventId.make(`event:projection-fork-source-rollback:assistant-item-${ordinal}`), type: "turn-item.updated", threadId: sourceThreadId, runId, nodeId, driver, occurredAt: now, payload: { id: TurnItemId.make(`turn-item:projection-fork-source-rollback:assistant:${ordinal}`), threadId: sourceThreadId, runId, nodeId, providerThreadId: sourceProviderThreadId, providerTurnId: null, nativeItemRef: null, parentItemId: null, ordinal: ordinal * 100 + 1, status: "completed", title: null, startedAt: now, completedAt: now, updatedAt: now, type: "assistant_message", messageId: MessageId.make( `message:projection-fork-source-rollback:assistant:${ordinal}`, ), text: responseText, streaming: false, }, }); } const targetBeforeRollback = yield* projectionStore.getThreadProjection(targetThreadId); assert.deepEqual( targetBeforeRollback.visibleTurnItems.map((row) => row.item.type), ["user_message", "assistant_message", "user_message", "assistant_message", "fork"], ); yield* projectionStore.apply({ id: EventId.make("event:projection-fork-source-rollback:run-2-rolled-back"), type: "run.updated", threadId: sourceThreadId, runId: sourceRun2Id, nodeId: sourceRun2NodeId, driver, occurredAt: now, payload: { id: sourceRun2Id, threadId: sourceThreadId, ordinal: 2, providerInstanceId, modelSelection, providerThreadId: sourceProviderThreadId, userMessageId: MessageId.make("message:projection-fork-source-rollback:user:2"), rootNodeId: sourceRun2NodeId, activeAttemptId: null, status: "rolled_back", requestedAt: now, startedAt: now, completedAt: now, checkpointId: null, contextHandoffId: null, }, }); const targetAfterRollback = yield* projectionStore.getThreadProjection(targetThreadId); assert.deepEqual( targetAfterRollback.visibleTurnItems.map((row) => [ row.visibility, row.item.type, row.item.type === "user_message" || row.item.type === "assistant_message" ? row.item.text : row.item.title, ]), [ ["inherited", "user_message", "source one"], ["inherited", "assistant_message", "one"], ["inherited", "user_message", "source two"], ["inherited", "assistant_message", "two"], ["synthetic", "fork", "Forked from conversation"], ], ); yield* projectionStore.apply({ id: EventId.make("event:projection-fork-source-rollback:run-3"), type: "run.updated", threadId: sourceThreadId, runId: sourceRun3Id, nodeId: sourceRun3NodeId, driver, occurredAt: now, payload: { id: sourceRun3Id, threadId: sourceThreadId, ordinal: 4, providerInstanceId, modelSelection, providerThreadId: sourceProviderThreadId, userMessageId: MessageId.make("message:projection-fork-source-rollback:user:3"), rootNodeId: sourceRun3NodeId, activeAttemptId: null, status: "completed", requestedAt: now, startedAt: now, completedAt: now, checkpointId: null, contextHandoffId: null, }, }); const nowIso = DateTime.formatIso(now); for (let index = 0; index < 300; index += 1) { const id = `turn-item:projection-fork-source-rollback:post-fork:${index}`; const ordinal = index < 10 ? 190 + index : 300 + index; yield* sql` INSERT INTO orchestration_v2_projection_turn_items ( turn_item_id, thread_id, run_id, node_id, provider_thread_id, provider_turn_id, parent_item_id, ordinal, type, status, updated_at, payload_json ) VALUES ( ${id}, ${sourceThreadId}, ${sourceRun3Id}, ${sourceRun3NodeId}, ${sourceProviderThreadId}, NULL, NULL, ${ordinal}, 'command_execution', 'completed', ${nowIso}, ${encodeUnknownJsonString({ id, threadId: sourceThreadId, runId: sourceRun3Id, nodeId: sourceRun3NodeId, providerThreadId: sourceProviderThreadId, providerTurnId: null, nativeItemRef: null, parentItemId: null, ordinal, status: "completed", title: "post fork", input: "echo later", output: "later", exitCode: 0, startedAt: nowIso, completedAt: nowIso, updatedAt: nowIso, type: "command_execution", })} ) `; } const boundedFork = yield* projectionStore.getThreadSnapshotWindow(targetThreadId, { rowLimit: 2, }); assert.lengthOf(boundedFork.projection.turnItems, 0); assert.deepEqual( boundedFork.projection.visibleTurnItems.map((row) => [row.visibility, row.item.type]), [ ["inherited", "user_message"], ["inherited", "assistant_message"], ["synthetic", "fork"], ], ); const parentPage = yield* projectionStore.getThreadSnapshotWindow(targetThreadId, { rowLimit: 2, anchorItemId: TurnItemId.make("turn-item:projection-fork-source-rollback:assistant:1"), }); assert.deepEqual( parentPage.projection.visibleTurnItems.map((row) => row.item.type === "user_message" || row.item.type === "assistant_message" ? row.item.text : row.item.type, ), ["source one", "one", "fork"], ); const emptyBoundaryRunId = RunId.make( "run:projection-fork-source-rollback:source:empty-boundary", ); yield* projectionStore.apply({ id: EventId.make("event:projection-fork-source-rollback:empty-boundary-run"), type: "run.updated", threadId: sourceThreadId, runId: emptyBoundaryRunId, nodeId: NodeId.make("node:projection-fork-source-rollback:source:empty-boundary"), driver, occurredAt: now, payload: { id: emptyBoundaryRunId, threadId: sourceThreadId, ordinal: 3, providerInstanceId, modelSelection, providerThreadId: sourceProviderThreadId, userMessageId: MessageId.make( "message:projection-fork-source-rollback:user:empty-boundary", ), rootNodeId: NodeId.make("node:projection-fork-source-rollback:source:empty-boundary"), activeAttemptId: null, status: "completed", requestedAt: now, startedAt: now, completedAt: now, checkpointId: null, contextHandoffId: null, }, }); yield* sql` UPDATE orchestration_v2_projection_threads SET payload_json = json_set(payload_json, '$.forkedFrom.runId', ${emptyBoundaryRunId}) WHERE thread_id = ${targetThreadId} `; const emptyBoundaryFork = yield* projectionStore.getThreadSnapshotWindow(targetThreadId, { rowLimit: 2, }); assert.deepEqual( emptyBoundaryFork.projection.visibleTurnItems.map((row) => row.item.type === "user_message" || row.item.type === "assistant_message" ? row.item.text : row.item.type, ), ["source two", "two", "fork"], ); yield* sql` UPDATE orchestration_v2_projection_threads SET payload_json = json_set(payload_json, '$.forkedFrom.runId', ${sourceRun2Id}) WHERE thread_id = ${targetThreadId} `; const targetRunId = RunId.make("run:projection-fork-source-rollback:target:1"); const targetNodeId = NodeId.make("node:projection-fork-source-rollback:target:1"); yield* projectionStore.apply({ id: EventId.make("event:projection-fork-source-rollback:target-run"), type: "run.updated", threadId: targetThreadId, runId: targetRunId, nodeId: targetNodeId, driver, occurredAt: now, payload: { id: targetRunId, threadId: targetThreadId, ordinal: 1, providerInstanceId, modelSelection, providerThreadId: targetProviderThreadId, userMessageId: MessageId.make("message:projection-fork-source-rollback:target:1"), rootNodeId: targetNodeId, activeAttemptId: null, status: "completed", requestedAt: now, startedAt: now, completedAt: now, checkpointId: null, contextHandoffId: null, }, }); for (let ordinal = 1; ordinal <= 2; ordinal += 1) { const id = `turn-item:projection-fork-source-rollback:target:${ordinal}`; yield* sql` INSERT INTO orchestration_v2_projection_turn_items ( turn_item_id, thread_id, run_id, node_id, provider_thread_id, provider_turn_id, parent_item_id, ordinal, type, status, updated_at, payload_json ) VALUES ( ${id}, ${targetThreadId}, ${targetRunId}, ${targetNodeId}, ${targetProviderThreadId}, NULL, NULL, ${ordinal}, 'command_execution', 'completed', ${nowIso}, ${encodeUnknownJsonString({ id, threadId: targetThreadId, runId: targetRunId, nodeId: targetNodeId, providerThreadId: targetProviderThreadId, providerTurnId: null, nativeItemRef: null, parentItemId: null, ordinal, status: "completed", title: `target ${ordinal}`, input: `echo target ${ordinal}`, output: "target", exitCode: 0, startedAt: nowIso, completedAt: nowIso, updatedAt: nowIso, type: "command_execution", })} ) `; } const nestedThreadId = ThreadId.make("thread:projection-fork-source-rollback:nested"); for (const ordinal of [ ...Array.from({ length: 99 }, (_, index) => index + 1), ...Array.from({ length: 99 }, (_, index) => index + 101), ]) { const runId = ordinal < 100 ? sourceRun1Id : sourceRun2Id; const id = `turn-item:projection-fork-source-rollback:lineage:${ordinal}`; yield* sql` INSERT INTO orchestration_v2_projection_turn_items ( turn_item_id, thread_id, run_id, node_id, provider_thread_id, provider_turn_id, parent_item_id, ordinal, type, status, updated_at, payload_json ) VALUES ( ${id}, ${sourceThreadId}, ${runId}, NULL, NULL, NULL, NULL, ${ordinal}, 'command_execution', 'completed', ${nowIso}, ${encodeUnknownJsonString({ id, threadId: sourceThreadId, runId, nodeId: null, providerThreadId: null, providerTurnId: null, nativeItemRef: null, parentItemId: null, ordinal, status: "completed", title: `lineage ${ordinal}`, input: "echo lineage", output: "lineage", exitCode: 0, startedAt: nowIso, completedAt: nowIso, updatedAt: nowIso, type: "command_execution", })} ) `; } const inheritedSupersededNodeId = NodeId.make( "node:projection-fork-source-rollback:inherited-superseded", ); yield* sql` INSERT INTO orchestration_v2_projection_run_attempts ( attempt_id, thread_id, run_id, attempt_ordinal, root_node_id, provider, provider_instance_id, provider_thread_id, provider_turn_id, status, payload_json ) VALUES ( 'attempt:projection-fork-source-rollback:inherited-superseded', ${sourceThreadId}, ${sourceRun2Id}, 2, ${inheritedSupersededNodeId}, 'codex', ${providerInstanceId}, ${sourceProviderThreadId}, NULL, 'superseded', ${encodeUnknownJsonString({ id: "attempt:projection-fork-source-rollback:inherited-superseded", runId: sourceRun2Id, attemptOrdinal: 2, rootNodeId: inheritedSupersededNodeId, providerInstanceId, providerThreadId: sourceProviderThreadId, providerTurnId: null, reason: "retry", status: "superseded", startedAt: nowIso, completedAt: nowIso, })} ) `; for (let ordinal = 201; ordinal <= 300; ordinal += 1) { const id = `turn-item:projection-fork-source-rollback:hidden-interrupt:${ordinal}`; yield* sql` INSERT INTO orchestration_v2_projection_turn_items ( turn_item_id, thread_id, run_id, node_id, provider_thread_id, provider_turn_id, parent_item_id, ordinal, type, status, updated_at, payload_json ) VALUES ( ${id}, ${sourceThreadId}, ${sourceRun2Id}, ${inheritedSupersededNodeId}, ${sourceProviderThreadId}, NULL, NULL, ${ordinal}, 'run_interrupt_result', 'completed', ${nowIso}, ${encodeUnknownJsonString({ id, threadId: sourceThreadId, runId: sourceRun2Id, nodeId: inheritedSupersededNodeId, providerThreadId: sourceProviderThreadId, providerTurnId: null, nativeItemRef: null, parentItemId: null, ordinal, status: "completed", title: "Stopped", message: "Stopped", startedAt: nowIso, completedAt: nowIso, updatedAt: nowIso, type: "run_interrupt_result", })} ) `; } yield* projectionStore.apply({ id: EventId.make("event:projection-fork-source-rollback:nested-thread"), type: "thread.created", threadId: nestedThreadId, occurredAt: now, payload: { createdBy: "user", creationSource: "web", id: nestedThreadId, projectId, title: "Nested bounded fork", providerInstanceId, modelSelection, runtimeMode: "full-access", interactionMode: "default", branch: null, worktreePath: null, activeProviderThreadId: null, lineage: { parentThreadId: targetThreadId, relationshipToParent: "fork", rootThreadId: sourceThreadId, }, forkedFrom: { type: "run", threadId: targetThreadId, runId: targetRunId }, createdAt: now, updatedAt: now, archivedAt: null, settledOverride: null, settledAt: null, lastVisitedAt: null, deletedAt: null, }, }); const boundedNested = yield* projectionStore.getThreadSnapshotWindow(nestedThreadId, { rowLimit: 2, }); assert.deepEqual( boundedNested.projection.visibleTurnItems.map((row) => row.item.type), [ "user_message", "assistant_message", "fork", "command_execution", "command_execution", "fork", ], ); const nestedInitial = buildBoundedThreadProjection({ projection: yield* projectionStore .getThreadSnapshotWindow(nestedThreadId, { rowLimit: THREAD_HISTORY_PAGE_POLICY.maxItems + 2, }) .pipe(Effect.map((snapshot) => snapshot.projection)), snapshotSequence: 1, }); const expectedNestedIds = (yield* projectionStore.getThreadProjection( nestedThreadId, )).visibleTurnItems.map((row) => String(row.sourceItemId)); const nestedIds = nestedInitial.projection.visibleTurnItems.map((row) => String(row.sourceItemId), ); let nestedCursor = nestedInitial.historyCursor; let nestedPages = 1; while (nestedCursor !== null) { const decoded = decodeThreadHistoryCursor(nestedCursor); const snapshot = yield* projectionStore.getThreadSnapshotWindow(nestedThreadId, { rowLimit: THREAD_HISTORY_PAGE_POLICY.maxItems + 2, anchorItemId: TurnItemId.make(decoded.si), anchorThreadId: ThreadId.make(decoded.st), }); const page = selectHistoryPageFromCursor({ items: snapshot.projection.visibleTurnItems, cursor: nestedCursor, snapshotSequence: snapshot.snapshotSequence, }); nestedIds.unshift(...page.items.map((row) => String(row.sourceItemId))); nestedCursor = page.nextCursor; nestedPages += 1; } assert.isAtLeast(nestedPages, 3); assert.lengthOf(nestedIds, expectedNestedIds.length); assert.deepEqual(nestedIds, expectedNestedIds); const emptyMiddleThreadId = ThreadId.make( "thread:projection-fork-source-rollback:empty-middle", ); const emptyMiddleRunId = RunId.make("run:projection-fork-source-rollback:empty-middle"); yield* projectionStore.apply({ id: EventId.make("event:projection-fork-source-rollback:empty-middle-thread"), type: "thread.created", threadId: emptyMiddleThreadId, occurredAt: now, payload: { createdBy: "user", creationSource: "web", id: emptyMiddleThreadId, projectId, title: "Empty middle fork", providerInstanceId, modelSelection, runtimeMode: "full-access", interactionMode: "default", branch: null, worktreePath: null, activeProviderThreadId: null, lineage: { parentThreadId: sourceThreadId, relationshipToParent: "fork", rootThreadId: sourceThreadId, }, forkedFrom: { type: "run", threadId: sourceThreadId, runId: sourceRun2Id }, createdAt: now, updatedAt: now, archivedAt: null, settledOverride: null, settledAt: null, lastVisitedAt: null, deletedAt: null, }, }); yield* projectionStore.apply({ id: EventId.make("event:projection-fork-source-rollback:empty-middle-run"), type: "run.updated", threadId: emptyMiddleThreadId, runId: emptyMiddleRunId, nodeId: NodeId.make("node:projection-fork-source-rollback:empty-middle"), driver, occurredAt: now, payload: { id: emptyMiddleRunId, threadId: emptyMiddleThreadId, ordinal: 1, providerInstanceId, modelSelection, providerThreadId: null, userMessageId: MessageId.make("message:projection-fork-source-rollback:empty-middle"), rootNodeId: NodeId.make("node:projection-fork-source-rollback:empty-middle"), activeAttemptId: null, status: "completed", requestedAt: now, startedAt: now, completedAt: now, checkpointId: null, contextHandoffId: null, }, }); const emptyLeafThreadId = ThreadId.make("thread:projection-fork-source-rollback:empty-leaf"); yield* projectionStore.apply({ id: EventId.make("event:projection-fork-source-rollback:empty-leaf-thread"), type: "thread.created", threadId: emptyLeafThreadId, occurredAt: now, payload: { createdBy: "user", creationSource: "web", id: emptyLeafThreadId, projectId, title: "Leaf after empty fork", providerInstanceId, modelSelection, runtimeMode: "full-access", interactionMode: "default", branch: null, worktreePath: null, activeProviderThreadId: null, lineage: { parentThreadId: emptyMiddleThreadId, relationshipToParent: "fork", rootThreadId: sourceThreadId, }, forkedFrom: { type: "run", threadId: emptyMiddleThreadId, runId: emptyMiddleRunId, }, createdAt: now, updatedAt: now, archivedAt: null, settledOverride: null, settledAt: null, lastVisitedAt: null, deletedAt: null, }, }); const emptyMiddleSnapshot = yield* projectionStore.getThreadSnapshotWindow( emptyLeafThreadId, { rowLimit: 2 }, ); assert.deepEqual( emptyMiddleSnapshot.projection.visibleTurnItems.map((row) => [ row.sourceThreadId, row.item.type, ]), [ [sourceThreadId, "user_message"], [sourceThreadId, "assistant_message"], [sourceThreadId, "fork"], [emptyMiddleThreadId, "fork"], ], ); yield* sql` DELETE FROM orchestration_v2_projection_turn_items WHERE run_id IN (${sourceRun1Id}, ${sourceRun2Id}) `; const importedItemId = "turn-item:projection-fork-source-rollback:legacy-import"; yield* sql` INSERT INTO orchestration_v2_projection_turn_items ( turn_item_id, thread_id, run_id, node_id, provider_thread_id, provider_turn_id, parent_item_id, ordinal, type, status, updated_at, payload_json ) VALUES ( ${importedItemId}, ${sourceThreadId}, NULL, NULL, NULL, NULL, NULL, 50, 'assistant_message', 'completed', ${nowIso}, ${encodeUnknownJsonString({ id: importedItemId, threadId: sourceThreadId, runId: null, nodeId: null, providerThreadId: null, providerTurnId: null, nativeItemRef: null, parentItemId: null, ordinal: 50, status: "completed", title: null, startedAt: nowIso, completedAt: nowIso, updatedAt: nowIso, type: "assistant_message", messageId: MessageId.make("message:projection-fork-source-rollback:legacy-import"), text: "legacy import before empty fork", streaming: false, historyOrigin: "v1_import", })} ) `; yield* sql` UPDATE orchestration_v2_projection_threads SET payload_json = json_set(payload_json, '$.historyOrigin', 'v1_import') WHERE thread_id = ${sourceThreadId} `; yield* sql` UPDATE orchestration_v2_projection_threads SET payload_json = json_set(payload_json, '$.forkedFrom.runId', ${emptyBoundaryRunId}) WHERE thread_id = ${targetThreadId} `; const importedEmptyBoundary = yield* projectionStore.getThreadSnapshotWindow(targetThreadId, { rowLimit: 2, }); assert.deepEqual( importedEmptyBoundary.projection.visibleTurnItems.map((row) => [ row.visibility, row.sourceThreadId, row.item.type === "assistant_message" ? row.item.text : row.item.type, ]), [ ["inherited", sourceThreadId, "legacy import before empty fork"], ["synthetic", sourceThreadId, "fork"], ["local", targetThreadId, "command_execution"], ["local", targetThreadId, "command_execution"], ], ); }), ); });