Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
b723e88
Add VCS checkpoint capability
justsomelegs May 7, 2026
5685038
Improve VCS diff benchmarks and process runner prototype
justsomelegs May 7, 2026
1ebae09
Refactor collected process error handling
justsomelegs May 7, 2026
2e5afe6
Optimize full-thread checkpoint diffs
justsomelegs May 7, 2026
6a29050
Remove benchmark artifacts
justsomelegs May 7, 2026
10f14d8
Rename collected process primitive to captured process
justsomelegs May 7, 2026
999bf91
Fix captured process timeout semantics
justsomelegs May 7, 2026
116e7a5
Optimize VcsProcess run on Effect
justsomelegs May 8, 2026
df7b877
Reduce checkpoint diff tail latency
justsomelegs May 8, 2026
daaca10
Optimize diff output collection
justsomelegs May 8, 2026
cfe902e
Use runCollect for diff output
justsomelegs May 8, 2026
9a7bca1
Revert "Use runCollect for diff output"
justsomelegs May 8, 2026
f01c402
Fix VcsDriverRegistry test for git -C invocations
justsomelegs May 8, 2026
6dae235
Unify process runner on Effect
justsomelegs May 8, 2026
67d8732
Make process runner dependencies explicit
justsomelegs May 8, 2026
52c027a
Clarify process timeout semantics
justsomelegs May 8, 2026
6fb343c
Enforce process output limits eagerly
justsomelegs May 8, 2026
2e713a8
Make process runner API explicit
justsomelegs May 8, 2026
10861b8
Fix Effect typecheck compatibility after rebase
justsomelegs May 8, 2026
00284b0
Fix Git truncation marker forwarding
justsomelegs May 8, 2026
01be4db
Forward-port archived projection snapshot query
justsomelegs May 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ import {
import { deriveServerPaths, ServerConfig } from "../src/config.ts";
import { WorkspaceEntriesLive } from "../src/workspace/Layers/WorkspaceEntries.ts";
import { WorkspacePathsLive } from "../src/workspace/Layers/WorkspacePaths.ts";
import * as GitVcsDriver from "../src/vcs/GitVcsDriver.ts";
import * as VcsDriverRegistry from "../src/vcs/VcsDriverRegistry.ts";
import { VcsStatusBroadcaster } from "../src/vcs/VcsStatusBroadcaster.ts";
import { GitWorkflowService } from "../src/git/GitWorkflowService.ts";
Expand Down Expand Up @@ -311,8 +310,11 @@ export const makeOrchestrationIntegrationHarness = (
Layer.provideMerge(serverSettingsLayer),
);
const gitWorkflowLayer = Layer.mock(GitWorkflowService)({
renameBranch: (input: Parameters<GitVcsDriver.GitVcsDriverShape["renameBranch"]>[0]) =>
Effect.succeed({ branch: input.newBranch }),
renameBranch: (input: {
readonly cwd: string;
readonly oldBranch: string;
readonly newBranch: string;
}) => Effect.succeed({ branch: input.newBranch }),
});
const textGenerationLayer = Layer.succeed(TextGeneration, {
generateBranchName: () => Effect.succeed({ branch: "update" }),
Expand Down
175 changes: 168 additions & 7 deletions apps/server/src/checkpointing/Layers/CheckpointDiffQuery.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,110 @@ function makeThreadCheckpointContext(input: {
}

describe("CheckpointDiffQueryLive", () => {
it("uses the narrow full-thread context lookup for all-turns diffs", async () => {
const projectId = ProjectId.make("project-full-thread");
const threadId = ThreadId.make("thread-full-thread");
const toCheckpointRef = checkpointRefForThreadTurn(threadId, 4);
let getThreadCheckpointContextCalls = 0;
let getFullThreadDiffContextCalls = 0;
const diffCheckpointsCalls: Array<{
readonly fromCheckpointRef: CheckpointRef;
readonly toCheckpointRef: CheckpointRef;
readonly cwd: string;
readonly ignoreWhitespace: boolean;
}> = [];

const checkpointStore: CheckpointStoreShape = {
isGitRepository: () => Effect.succeed(true),
captureCheckpoint: () => Effect.void,
hasCheckpointRef: () => Effect.succeed(true),
restoreCheckpoint: () => Effect.succeed(true),
diffCheckpoints: ({ fromCheckpointRef, toCheckpointRef, cwd, ignoreWhitespace }) =>
Effect.sync(() => {
diffCheckpointsCalls.push({
fromCheckpointRef,
toCheckpointRef,
cwd,
ignoreWhitespace,
});
return "full thread diff patch";
}),
deleteCheckpointRefs: () => Effect.void,
};

const layer = CheckpointDiffQueryLive.pipe(
Layer.provideMerge(Layer.succeed(CheckpointStore, checkpointStore)),
Layer.provideMerge(
Layer.succeed(ProjectionSnapshotQuery, {
getCommandReadModel: () =>
Effect.die("CheckpointDiffQuery should not request the command read model"),
getSnapshot: () =>
Effect.die("CheckpointDiffQuery should not request the full orchestration snapshot"),
getShellSnapshot: () =>
Effect.die("CheckpointDiffQuery should not request the orchestration shell snapshot"),
getArchivedShellSnapshot: () =>
Effect.die("CheckpointDiffQuery should not request archived shell snapshots"),
getSnapshotSequence: () => Effect.succeed({ snapshotSequence: 0 }),
getCounts: () => Effect.succeed({ projectCount: 0, threadCount: 0 }),
getActiveProjectByWorkspaceRoot: () => Effect.succeed(Option.none()),
getProjectShellById: () => Effect.succeed(Option.none()),
getFirstActiveThreadIdByProjectId: () => Effect.succeed(Option.none()),
getThreadCheckpointContext: () =>
Effect.sync(() => {
getThreadCheckpointContextCalls += 1;
return Option.none();
}),
getFullThreadDiffContext: () =>
Effect.sync(() => {
getFullThreadDiffContextCalls += 1;
return Option.some({
threadId,
projectId,
workspaceRoot: "/tmp/workspace",
worktreePath: "/tmp/worktree",
latestCheckpointTurnCount: 4,
toCheckpointRef,
});
}),
getThreadShellById: () => Effect.succeed(Option.none()),
getThreadDetailById: () => Effect.succeed(Option.none()),
}),
),
);

const result = await Effect.runPromise(
Effect.gen(function* () {
const query = yield* CheckpointDiffQuery;
return yield* query.getFullThreadDiff({
threadId,
toTurnCount: 4,
ignoreWhitespace: true,
});
}).pipe(Effect.provide(layer)),
);

expect(getThreadCheckpointContextCalls).toBe(0);
expect(getFullThreadDiffContextCalls).toBe(1);
expect(diffCheckpointsCalls).toEqual([
{
cwd: "/tmp/worktree",
fromCheckpointRef: checkpointRefForThreadTurn(threadId, 0),
toCheckpointRef,
ignoreWhitespace: true,
},
]);
expect(result).toEqual({
threadId,
fromTurnCount: 0,
toTurnCount: 4,
diff: "full thread diff patch",
});
});

it("computes diffs using canonical turn-0 checkpoint refs", async () => {
const projectId = ProjectId.make("project-1");
const threadId = ThreadId.make("thread-1");
const toCheckpointRef = checkpointRefForThreadTurn(threadId, 1);
const hasCheckpointRefCalls: Array<CheckpointRef> = [];
const diffCheckpointsCalls: Array<{
readonly fromCheckpointRef: CheckpointRef;
readonly toCheckpointRef: CheckpointRef;
Expand All @@ -65,11 +164,7 @@ describe("CheckpointDiffQueryLive", () => {
const checkpointStore: CheckpointStoreShape = {
isGitRepository: () => Effect.succeed(true),
captureCheckpoint: () => Effect.void,
hasCheckpointRef: ({ checkpointRef }) =>
Effect.sync(() => {
hasCheckpointRefCalls.push(checkpointRef);
return true;
}),
hasCheckpointRef: () => Effect.succeed(true),
restoreCheckpoint: () => Effect.succeed(true),
diffCheckpoints: ({ fromCheckpointRef, toCheckpointRef, cwd, ignoreWhitespace }) =>
Effect.sync(() => {
Expand Down Expand Up @@ -121,7 +216,6 @@ describe("CheckpointDiffQueryLive", () => {
);

const expectedFromRef = checkpointRefForThreadTurn(threadId, 0);
expect(hasCheckpointRefCalls).toEqual([expectedFromRef, toCheckpointRef]);
expect(diffCheckpointsCalls).toEqual([
{
cwd: "/tmp/workspace",
Expand Down Expand Up @@ -204,6 +298,73 @@ describe("CheckpointDiffQueryLive", () => {
expect(diffCheckpointsCalls).toEqual([{ ignoreWhitespace: true }]);
});

it("does not preflight checkpoint refs before diffing", async () => {
const projectId = ProjectId.make("project-no-preflight");
const threadId = ThreadId.make("thread-no-preflight");
const toCheckpointRef = checkpointRefForThreadTurn(threadId, 1);
let hasCheckpointRefCallCount = 0;

const threadCheckpointContext = makeThreadCheckpointContext({
projectId,
threadId,
workspaceRoot: "/tmp/workspace",
worktreePath: null,
checkpointTurnCount: 1,
checkpointRef: toCheckpointRef,
});

const checkpointStore: CheckpointStoreShape = {
isGitRepository: () => Effect.succeed(true),
captureCheckpoint: () => Effect.void,
hasCheckpointRef: () =>
Effect.sync(() => {
hasCheckpointRefCallCount += 1;
return true;
}),
restoreCheckpoint: () => Effect.succeed(true),
diffCheckpoints: () => Effect.succeed("diff patch"),
deleteCheckpointRefs: () => Effect.void,
};

const layer = CheckpointDiffQueryLive.pipe(
Layer.provideMerge(Layer.succeed(CheckpointStore, checkpointStore)),
Layer.provideMerge(
Layer.succeed(ProjectionSnapshotQuery, {
getCommandReadModel: () =>
Effect.die("CheckpointDiffQuery should not request the command read model"),
getSnapshot: () =>
Effect.die("CheckpointDiffQuery should not request the full orchestration snapshot"),
getShellSnapshot: () =>
Effect.die("CheckpointDiffQuery should not request the orchestration shell snapshot"),
getArchivedShellSnapshot: () =>
Effect.die("CheckpointDiffQuery should not request archived shell snapshots"),
getSnapshotSequence: () => Effect.succeed({ snapshotSequence: 0 }),
getCounts: () => Effect.succeed({ projectCount: 0, threadCount: 0 }),
getActiveProjectByWorkspaceRoot: () => Effect.succeed(Option.none()),
getProjectShellById: () => Effect.succeed(Option.none()),
getFirstActiveThreadIdByProjectId: () => Effect.succeed(Option.none()),
getThreadCheckpointContext: () => Effect.succeed(Option.some(threadCheckpointContext)),
getThreadShellById: () => Effect.succeed(Option.none()),
getThreadDetailById: () => Effect.succeed(Option.none()),
}),
),
);

await Effect.runPromise(
Effect.gen(function* () {
const query = yield* CheckpointDiffQuery;
return yield* query.getTurnDiff({
threadId,
fromTurnCount: 0,
toTurnCount: 1,
ignoreWhitespace: true,
});
}).pipe(Effect.provide(layer)),
);

expect(hasCheckpointRefCallCount).toBe(0);
});

it("fails when the thread is missing from the snapshot", async () => {
const threadId = ThreadId.make("thread-missing");

Expand Down
Loading
Loading