import { assert, it } from "@effect/vitest"; import { CheckpointId, CheckpointRef, CheckpointScopeId, EventId, MessageId, NodeId, type OrchestrationV2DomainEvent, type OrchestrationV2Run, ProjectId, ProviderDriverKind, ProviderInstanceId, ProviderThreadId, RunId, ThreadId, } from "@t3tools/contracts"; import * as DateTime from "effect/DateTime"; import * as Effect from "effect/Effect"; import * as Layer from "effect/Layer"; import * as Ref from "effect/Ref"; import { SqlitePersistenceMemory } from "../persistence/Layers/Sqlite.ts"; import { CheckpointServiceV2 } from "./CheckpointService.ts"; import * as CheckpointCaptureService from "./CheckpointCaptureService.ts"; import { EventSinkV2 } from "./EventSink.ts"; import * as IdAllocator from "./IdAllocator.ts"; import * as ProjectionStore from "./ProjectionStore.ts"; const ProjectionStoreTestLayer = Layer.mergeAll( ProjectionStore.layer.pipe(Layer.provideMerge(SqlitePersistenceMemory)), SqlitePersistenceMemory, ); const threadId = ThreadId.make("thread:checkpoint-capture-delegated"); const projectId = ProjectId.make("project:checkpoint-capture-delegated"); const runId = RunId.make("run:checkpoint-capture-delegated"); const scopeId = CheckpointScopeId.make("scope:checkpoint-capture-delegated"); const rootNodeId = NodeId.make("node:checkpoint-capture-delegated-root"); const taskId = NodeId.make("node:checkpoint-capture-task"); const deliveryMessageId = MessageId.make("message:checkpoint-capture-delivery"); const providerThreadId = ProviderThreadId.make("provider-thread:checkpoint-capture-delegated"); const providerInstanceId = ProviderInstanceId.make("codex"); const driver = ProviderDriverKind.make("codex"); const modelSelection = { instanceId: providerInstanceId, model: "gpt-5.4", } as const; it.layer(ProjectionStoreTestLayer)("CheckpointCaptureServiceV2", (it) => { it.effect( "preserves a newer delegatedCompletion cohort when checkpoint run.updated is applied after it", () => Effect.gen(function* () { const projectionStore = yield* ProjectionStore.ProjectionStoreV2; const now = yield* DateTime.now; const later = DateTime.add(now, { seconds: 1 }); const staleDelegatedCompletion = { disposition: "open" as const, nextGeneration: 1, settledDeliveryCount: 0, delivery: null, }; const newerCohort = { disposition: "open" as const, nextGeneration: 2, settledDeliveryCount: 1, delivery: { generation: 1, messageId: deliveryMessageId, taskIds: [taskId], }, }; const staleRun: OrchestrationV2Run = { id: runId, threadId, ordinal: 1, providerInstanceId, modelSelection, providerThreadId, userMessageId: MessageId.make("message:checkpoint-capture-user"), rootNodeId, activeAttemptId: null, status: "waiting", requestedAt: now, startedAt: now, completedAt: null, checkpointId: null, contextHandoffId: null, // Snapshot taken before a concurrent cohort advanced during capture work. delegatedCompletion: staleDelegatedCompletion, }; const rootNode = { id: rootNodeId, threadId, runId, parentNodeId: null, rootNodeId, kind: "root_turn" as const, status: "waiting" as const, countsForRun: true, providerThreadId, providerTurnId: null, nativeItemRef: null, runtimeRequestId: null, checkpointScopeId: scopeId, startedAt: now, completedAt: null, }; const scope = { id: scopeId, threadId, runId, nodeId: rootNodeId, parentScopeId: null, providerThreadId, kind: "root_run" as const, ordinalWithinParent: 0, advancesAppRunCount: true, cwd: "/repo", createdAt: now, }; const providerThread = { id: providerThreadId, driver, providerInstanceId, providerSessionId: null, appThreadId: threadId, ownerNodeId: rootNodeId, nativeThreadRef: null, nativeConversationHeadRef: null, status: "idle" as const, firstRunOrdinal: 1, lastRunOrdinal: 1, handoffIds: [], forkedFrom: null, createdAt: now, updatedAt: now, }; const readyBaseline = { id: CheckpointId.make("checkpoint:baseline-0"), threadId, scopeId, runId: null, nodeId: rootNodeId, parentCheckpointId: null, ordinalWithinScope: 0, appRunOrdinal: null, ref: CheckpointRef.make("checkpoint-ref:baseline-0"), status: "ready" as const, files: [], capturedAt: now, }; const captured = { id: CheckpointId.make("checkpoint:captured-1"), threadId, scopeId, runId, nodeId: rootNodeId, parentCheckpointId: readyBaseline.id, ordinalWithinScope: 1, appRunOrdinal: 1, ref: CheckpointRef.make("checkpoint-ref:captured-1"), status: "ready" as const, files: [], capturedAt: now, }; yield* projectionStore.apply({ id: EventId.make("event:checkpoint-capture:thread"), type: "thread.created", threadId, occurredAt: now, payload: { createdBy: "user", creationSource: "web", id: threadId, projectId, title: "Checkpoint capture delegated completion", 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:checkpoint-capture:run-stale"), type: "run.updated", threadId, runId, nodeId: rootNodeId, providerInstanceId, occurredAt: now, payload: staleRun, }); yield* projectionStore.apply({ id: EventId.make("event:checkpoint-capture:node"), type: "node.updated", threadId, runId, nodeId: rootNodeId, providerInstanceId, occurredAt: now, payload: rootNode, }); yield* projectionStore.apply({ id: EventId.make("event:checkpoint-capture:provider-thread"), type: "provider-thread.updated", threadId, nodeId: rootNodeId, driver, providerInstanceId, occurredAt: now, payload: providerThread, }); yield* projectionStore.apply({ id: EventId.make("event:checkpoint-capture:scope"), type: "checkpoint-scope.created", threadId, runId, nodeId: rootNodeId, occurredAt: now, payload: scope, }); yield* projectionStore.apply({ id: EventId.make("event:checkpoint-capture:baseline"), type: "checkpoint.captured", threadId, nodeId: rootNodeId, driver, providerInstanceId, occurredAt: now, payload: readyBaseline, }); const committed = yield* Ref.make>([]); const captureLayer = CheckpointCaptureService.layer.pipe( Layer.provide( Layer.mergeAll( IdAllocator.layer, Layer.mock(CheckpointServiceV2)({ materializeBaselineCheckpoint: () => Effect.die("baseline materialization must be skipped when ordinal 0 is ready"), capture: () => Effect.succeed(captured), }), Layer.mock(EventSinkV2)({ commitCommand: (input) => Ref.set(committed, input.events).pipe( Effect.as({ commandId: input.commandId, committed: true, sequence: 1, events: input.events, effects: [], } as never), ), }), ), ), ); yield* Effect.gen(function* () { const service = yield* CheckpointCaptureService.CheckpointCaptureServiceV2; // Capture reads the waiting run while the projection still holds the stale cohort. yield* service.execute({ threadId, runId, scopeId }); const events = yield* Ref.get(committed); const runUpdated = events.find((event) => event.type === "run.updated"); assert.isDefined(runUpdated); if (runUpdated?.type !== "run.updated") { return; } assert.equal(runUpdated.payload.status, "completed"); assert.equal(runUpdated.payload.checkpointId, captured.id); assert.isUndefined( runUpdated.payload.delegatedCompletion, "checkpoint capture must omit delegatedCompletion so ProjectionStore can keep a newer cohort", ); // Race: a newer cohort lands on the projection after capture read the stale // waiting run and before the capture command's run.updated is applied. yield* projectionStore.apply({ id: EventId.make("event:checkpoint-capture:newer-cohort"), type: "run.updated", threadId, runId, nodeId: rootNodeId, providerInstanceId, occurredAt: later, payload: { ...staleRun, delegatedCompletion: newerCohort, }, }); // Apply the real capture-emitted run.updated through ProjectionStore. yield* projectionStore.apply(runUpdated); const projection = yield* projectionStore.getThreadProjection(threadId); const projectedRun = projection.runs[0]; assert.isDefined(projectedRun); assert.equal(projectedRun?.status, "completed"); assert.equal(projectedRun?.checkpointId, captured.id); assert.deepEqual(projectedRun?.delegatedCompletion, newerCohort); assert.equal(projectedRun?.delegatedCompletion?.delivery?.messageId, deliveryMessageId); assert.deepEqual(projectedRun?.delegatedCompletion?.delivery?.taskIds, [taskId]); }).pipe(Effect.provide(captureLayer)); }), ); });