1import * as NodeCrypto from "@effect/platform-node/NodeCrypto";
2import { assert, it, vi } from "@effect/vitest";
3import {
4 CheckpointScopeId,
5 NodeId,
6 ProviderThreadId,
7 RunId,
8 ThreadId,
9 type OrchestrationV2CheckpointScope,
10 VcsProcessTimeoutError,
11} from "@t3tools/contracts";
12import * as DateTime from "effect/DateTime";
13import * as Effect from "effect/Effect";
14import * as Exit from "effect/Exit";
15import * as Layer from "effect/Layer";
16
17import * as CheckpointStore from "../checkpointing/CheckpointStore.ts";
18import * as CheckpointService from "./CheckpointService.ts";
19import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator";
20
21it.effect.each([false, true, "interrupt"] as const)(
22 "materializes baseline, lookup fails=%s",
23 (lookupFails) => {
24 const scope: OrchestrationV2CheckpointScope = {
25 id: CheckpointScopeId.make("checkpoint-scope:materialize-baseline"),
26 threadId: ThreadId.make("thread:materialize-baseline"),
27 runId: RunId.make("run:materialize-baseline:3"),
28 nodeId: NodeId.make("node:materialize-baseline:3"),
29 parentScopeId: null,
30 providerThreadId: ProviderThreadId.make("provider-thread:materialize-baseline"),
31 kind: "root_run",
32 ordinalWithinParent: 0,
33 advancesAppRunCount: true,
34 cwd: "/repo",
35 createdAt: DateTime.makeUnsafe("2026-07-28T00:00:00.000Z"),
36 };
37 const hasCheckpointRef = vi.fn((_input: CheckpointStore.RestoreCheckpointInput) =>
38 lookupFails === "interrupt"
39 ? Effect.interrupt
40 : lookupFails
41 ? Effect.fail(
42 new VcsProcessTimeoutError({
43 operation: "test.ref",
44 command: "git",
45 cwd: "/repo",
46 timeoutMs: 30000,
47 }),
48 )
49 : Effect.succeed(true),
50 );
51 const layerTest = CheckpointService.layer.pipe(
52 Layer.provide(
53 Layer.mergeAll(
54 IdAllocator.layer,
55 Layer.mock(CheckpointStore.CheckpointStore)({
56 isGitRepository: () => Effect.succeed(true),
57 hasCheckpointRef,
58 captureCheckpoint: () => Effect.void,
59 }),
60 ),
61 ),
62 Layer.provideMerge(NodeCrypto.layer),
63 );
64
65 return Effect.gen(function* () {
66 const checkpoints = yield* CheckpointService.CheckpointServiceV2;
67 if (lookupFails === "interrupt") {
68 const exit = yield* Effect.exit(
69 checkpoints.materializeBaselineCheckpoint({ scope, ordinalWithinScope: 2 }),
70 );
71 assert.isTrue(Exit.hasInterrupts(exit));
72 const captureExit = yield* Effect.exit(
73 checkpoints.capture({
74 scope,
75 ordinalWithinScope: 1,
76 runId: scope.runId!,
77 nodeId: scope.nodeId!,
78 appRunOrdinal: 1,
79 capturedAt: scope.createdAt,
80 }),
81 );
82 assert.isTrue(Exit.hasInterrupts(captureExit));
83 return;
84 }
85 const baseline = yield* checkpoints.materializeBaselineCheckpoint({
86 scope,
87 ordinalWithinScope: 2,
88 });
89
90 assert.equal(baseline.ordinalWithinScope, 2);
91 assert.equal(
92 baseline.ref,
93 yield* CheckpointService.checkpointRefForScopeOrdinal({
94 scopeId: scope.id,
95 ordinalWithinScope: 2,
96 }),
97 );
98 assert.equal(baseline.status, lookupFails ? "missing" : "ready");
99 assert.deepEqual(hasCheckpointRef.mock.calls[0]?.[0], {
100 cwd: scope.cwd,
101 checkpointRef: baseline.ref,
102 });
103 }).pipe(Effect.provide(layerTest));
104 },
105);