feat: map demo beats to replay readiness

This commit is contained in:
lda
2026-07-09 15:13:57 +07:00 Verified
parent e879f18c4f
commit eaf2436cb2
2 changed files with 69 additions and 0 deletions
@@ -0,0 +1,23 @@
import { describe, expect, it } from "vitest";
import { requirementForDemoBeat } from "./demo-beat-requirements.js";
describe("requirementForDemoBeat", () => {
it.each([
["workflow-demo", "operation", "run_start"],
["workflow-demo", "graph", "run_start"],
["workflow-demo", "interrupt", "interrupt"],
["interrupt-evidence", "approval", "interrupt"],
["interrupt-evidence", "resume", "run_resume"],
["interrupt-evidence", "output", "run_resume"],
["interrupt-evidence", "trace", "trace_read"],
] as const)("maps %s/%s to %s", (sceneId, beatId, stage) => {
expect(requirementForDemoBeat(sceneId, beatId).requiredStage).toBe(stage);
});
it("returns no required stage for non-demo beats", () => {
expect(requirementForDemoBeat("thesis", "title")).toEqual({
requiredStage: null,
reason: "No demo replay state needed.",
});
});
});
@@ -0,0 +1,46 @@
import type { DemoEvent } from "../demo/timeline/models.js";
export type DemoBeatRequirement = {
readonly requiredStage: DemoEvent["stage"] | null;
readonly reason: string;
};
const requirements: Readonly<Record<string, DemoBeatRequirement>> = {
"workflow-demo/operation": {
requiredStage: "run_start",
reason: "Operation beat needs the recorded run start.",
},
"workflow-demo/graph": {
requiredStage: "run_start",
reason: "Graph beat needs the persisted run id.",
},
"workflow-demo/interrupt": {
requiredStage: "interrupt",
reason: "Interrupt beat needs the typed review payload.",
},
"interrupt-evidence/approval": {
requiredStage: "interrupt",
reason: "Approval beat needs the typed review payload before controls can act.",
},
"interrupt-evidence/resume": {
requiredStage: "run_resume",
reason: "Resume beat needs the recorded resume operation.",
},
"interrupt-evidence/output": {
requiredStage: "run_resume",
reason: "Output beat needs the resumed run output.",
},
"interrupt-evidence/trace": {
requiredStage: "trace_read",
reason: "Trace beat needs the recorded trace read.",
},
};
export const requirementForDemoBeat = (
sceneId: string,
beatId: string,
): DemoBeatRequirement =>
requirements[`${sceneId}/${beatId}`] ?? {
requiredStage: null,
reason: "No demo replay state needed.",
};