feat(app): define trusted rewind branch flow

This commit is contained in:
Codex
2026-07-28 03:23:57 -04:00
parent cf9507a9dd
commit 497c127e87
15 changed files with 671 additions and 26 deletions
+26 -2
View File
@@ -1,9 +1,9 @@
import { describe, expect, it } from "vitest";
import initialView from "../../fixtures/player-view/initial.json";
import type { PlayerView, TurnRequest } from "@contracts";
import type { ForkBranchRequest, PlayerView, TurnRequest } from "@contracts";
import { submitDemoTurn } from "./turnAdapter";
import { forkDemoBranch, submitDemoTurn } from "./turnAdapter";
function request(intent: TurnRequest["intent"], input: string): TurnRequest {
return {
@@ -36,4 +36,28 @@ describe("local turn adapter", () => {
expect(result.playerView.beats.some((beat) => beat.speaker === "你")).toBe(false);
expect(result.playerView.beats.at(-1)?.speaker).toBe("娜娜");
});
it("mirrors a fork without moving or deleting the source history", async () => {
const advanced = await submitDemoTurn(
request("speak_or_act", "我先去看看站台。"),
initialView as PlayerView
);
const forkRequest: ForkBranchRequest = {
storyId: advanced.playerView.storyId,
currentBranchId: advanced.playerView.branchId,
expectedCurrentNodeId: advanced.playerView.nodeId,
sourceNodeId: initialView.nodeId,
actionId: "fork_adapter_test"
};
const forked = await forkDemoBranch(forkRequest, advanced.playerView);
expect(forked.branchId).toBe("branch_fork_adapter_test");
expect(forked.playerView.nodeId).toBe(initialView.nodeId);
expect(forked.playerView.branchId).toBe(forked.branchId);
expect(forked.playerView.history).toHaveLength(1);
expect(forked.playerView.history[0]?.isCurrent).toBe(true);
expect(advanced.playerView.branchId).toBe(initialView.branchId);
expect(advanced.playerView.nodeId).toBe("node_002");
});
});