feat: model demo climax beats

This commit is contained in:
lda
2026-07-08 23:12:59 +07:00 Verified
parent 79a4081c8d
commit 66d4eed3f8
2 changed files with 122 additions and 0 deletions
@@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest";
import type { DemoEvent } from "../demo/timeline/models.js";
import { loadCanonicalDemoRecording } from "../demo/timeline/replay.js";
import {
demoBeatLensForBeat,
graphExecutionForBeat,
projectInterruptContract,
projectOperationPresentation,
@@ -70,3 +71,48 @@ describe("demo workflow presentation model", () => {
});
});
});
describe("demo beat lens", () => {
it("defines a product-story phase for every Scene 9 and Scene 10 beat", () => {
const beatIds = ["operation", "graph", "interrupt", "approval", "resume", "output", "trace"];
expect(beatIds.map((beatId) => demoBeatLensForBeat(beatId).phase)).toEqual([
"agent",
"run",
"interrupt",
"interrupt",
"resume",
"evidence",
"evidence",
]);
});
it("uses stable audience-facing labels for the demo climax", () => {
expect(demoBeatLensForBeat("operation")).toMatchObject({
eyebrow: "Agent handoff",
headline: "Request becomes a workflow run",
proofLabel: "workflow.runs.start",
});
expect(demoBeatLensForBeat("approval")).toMatchObject({
eyebrow: "Typed human boundary",
headline: "The run waits for an explicit resume decision",
proofLabel: "issue_review",
});
expect(demoBeatLensForBeat("trace")).toMatchObject({
eyebrow: "Evidence remains",
headline: "The result can still be inspected after the demo",
proofLabel: "trace frames",
});
});
it("keeps graph execution continuity across the interrupt and resume beats", () => {
expect(graphExecutionForBeat("approval")).toEqual(graphExecutionForBeat("interrupt"));
expect(graphExecutionForBeat("resume")).toMatchObject({
completedNodeIds: ["read_docs", "build_report", "review_issues"],
currentNodeId: "create_issues",
});
expect(graphExecutionForBeat("trace")).toMatchObject({
currentNodeId: "end_completed",
});
});
});