refactor: consolidate authoring defense story

This commit is contained in:
lda
2026-07-13 12:03:43 +07:00 Verified
parent b0cefc7577
commit 708445a8f1
7 changed files with 96 additions and 66 deletions
@@ -36,8 +36,8 @@ describe("PresentationFooter", () => {
/>,
);
const footer = screen.getByRole("contentinfo", { name: /presentation footer/i });
expect(within(footer).getByText("6 / 14")).toBeInTheDocument();
expect(within(footer).getByText("4 / 5")).toBeInTheDocument();
expect(within(footer).getByText("6 / 13")).toBeInTheDocument();
expect(within(footer).getByText("4 / 4")).toBeInTheDocument();
expect(within(footer).getByText(/workflow\.runs\.trace/)).toBeInTheDocument();
});
@@ -22,8 +22,8 @@ describe("SceneProgress", () => {
render(<SceneProgress location={location} />);
expect(screen.getByText("6 / 14")).toBeInTheDocument();
expect(screen.getByText("4 / 5")).toBeInTheDocument();
expect(screen.getByText("6 / 13")).toBeInTheDocument();
expect(screen.getByText("4 / 4")).toBeInTheDocument();
});
it("shows scene position for run-from-deployment/graph", () => {
@@ -36,11 +36,11 @@ describe("SceneProgress", () => {
render(<SceneProgress location={location} />);
expect(screen.getByText("10 / 14")).toBeInTheDocument();
expect(screen.getByText("9 / 13")).toBeInTheDocument();
expect(screen.getByText("3 / 3")).toBeInTheDocument();
});
it("shows the single Scene 8 beat position", () => {
it("shows the single Scene 7 beat position", () => {
const location: MainLocation = {
kind: "main",
sceneId: "agent-handoff",
@@ -50,7 +50,7 @@ describe("SceneProgress", () => {
render(<SceneProgress location={location} />);
expect(screen.getByText("8 / 14")).toBeInTheDocument();
expect(screen.getByText("7 / 13")).toBeInTheDocument();
expect(screen.getByText("1 / 1")).toBeInTheDocument();
});
@@ -68,10 +68,34 @@ describe("presentation coherence matrix", () => {
});
it("defines semantic zoom for architecture and evidence staging for evaluation", () => {
expect(beatVisualContractFor("architecture", "node-use")).toMatchObject({
expect(beatVisualContractFor("architecture", "runtime")).toMatchObject({
mode: "zoom",
primarySurface: "interactive-architecture",
});
expect(beatVisualContractFor("prepared-lifecycle", "discover")).toMatchObject({
mode: "evidence",
primarySurface: "prepared-discovery",
});
expect(beatVisualContractFor("prepared-lifecycle", "draft")).toMatchObject({
mode: "evidence",
primarySurface: "draft-graph",
});
expect(beatVisualContractFor("prepared-lifecycle", "diagnose")).toMatchObject({
mode: "evidence",
primarySurface: "prepared-diagnostic",
});
expect(beatVisualContractFor("prepared-lifecycle", "repair")).toMatchObject({
mode: "evidence",
primarySurface: "prepared-repair",
});
expect(beatVisualContractFor("prepared-lifecycle", "artifact")).toMatchObject({
mode: "evidence",
primarySurface: "artifact",
});
expect(beatVisualContractFor("prepared-lifecycle", "deployment")).toMatchObject({
mode: "evidence",
primarySurface: "deployment",
});
expect(beatVisualContractFor("evaluation", "validity")).toMatchObject({
mode: "evidence",
primarySurface: "evaluation-validity",
@@ -5,7 +5,6 @@ export type PrimaryArtifact =
| "boundary-diagram"
| "lifecycle-rail"
| "interactive-architecture"
| "authoring-loop"
| "agent-handoff"
| "prepared-lifecycle"
| "workflow-graph"
@@ -85,13 +84,6 @@ export const sceneCoherenceMatrix = [
chatRole: "hidden",
presenterFocus: "Use the recursive architecture figure as the only primary artifact.",
},
{
sceneId: "authoring",
primaryArtifact: "authoring-loop",
supportSurface: "discussion-rail",
chatRole: "hidden",
presenterFocus: "Show the authoring loop without turning it into generic process cards.",
},
{
sceneId: "agent-handoff",
primaryArtifact: "agent-handoff",
@@ -152,11 +144,12 @@ const beatContracts = {
"architecture/client": { mode: "zoom", primarySurface: "interactive-architecture", supportSurface: "none" },
"architecture/api": { mode: "zoom", primarySurface: "interactive-architecture", supportSurface: "none" },
"architecture/runtime": { mode: "zoom", primarySurface: "interactive-architecture", supportSurface: "none" },
"architecture/node-use": { mode: "zoom", primarySurface: "interactive-architecture", supportSurface: "evidence-receipt" },
"authoring/discover": { mode: "evidence", primarySurface: "authoring-discovery", supportSurface: "authoring-loop" },
"authoring/author": { mode: "evidence", primarySurface: "authoring-draft", supportSurface: "authoring-loop" },
"authoring/diagnose": { mode: "evidence", primarySurface: "authoring-diagnostic", supportSurface: "authoring-loop" },
"authoring/repair": { mode: "evidence", primarySurface: "authoring-repair", supportSurface: "authoring-loop" },
"prepared-lifecycle/discover": { mode: "evidence", primarySurface: "prepared-discovery", supportSurface: "none" },
"prepared-lifecycle/draft": { mode: "evidence", primarySurface: "draft-graph", supportSurface: "none" },
"prepared-lifecycle/diagnose": { mode: "evidence", primarySurface: "prepared-diagnostic", supportSurface: "none" },
"prepared-lifecycle/repair": { mode: "evidence", primarySurface: "prepared-repair", supportSurface: "none" },
"prepared-lifecycle/artifact": { mode: "evidence", primarySurface: "artifact", supportSurface: "none" },
"prepared-lifecycle/deployment": { mode: "evidence", primarySurface: "deployment", supportSurface: "none" },
"agent-handoff/request": { mode: "conversation", primarySurface: "prepared-conversation", supportSurface: "none" },
"evaluation/cohort": { mode: "evidence", primarySurface: "evaluation-cohort", supportSurface: "none" },
"evaluation/validity": { mode: "evidence", primarySurface: "evaluation-validity", supportSurface: "audit-reconciliation" },
@@ -7,10 +7,9 @@ const expectedBeats = {
positioning: ["landscape", "lda-position"],
"planner-runtime": ["planner", "runtime", "boundary"],
lifecycle: ["draft", "artifact", "deployment", "run"],
architecture: ["overview", "client", "api", "runtime", "node-use"],
authoring: ["discover", "author", "diagnose", "repair"],
architecture: ["overview", "client", "api", "runtime"],
"agent-handoff": ["request"],
"prepared-lifecycle": ["discover", "draft", "validate", "artifact", "deployment"],
"prepared-lifecycle": ["discover", "draft", "diagnose", "repair", "artifact", "deployment"],
"run-from-deployment": ["input", "operation", "graph"],
"typed-human-boundary": ["interrupt", "approval"],
"resume-output-evidence": ["resume", "output", "trace"],
@@ -9,8 +9,8 @@ import {
} from "./storyboard.js";
describe("defense storyboard catalog", () => {
it("defines fourteen ordered main scenes with unique scene and beat ids", () => {
expect(mainScenes).toHaveLength(14);
it("defines thirteen ordered main scenes with unique scene and beat ids", () => {
expect(mainScenes).toHaveLength(13);
expect(mainScenes.map((scene) => scene.id)).toEqual([
"thesis",
"problem",
@@ -18,7 +18,6 @@ describe("defense storyboard catalog", () => {
"planner-runtime",
"lifecycle",
"architecture",
"authoring",
"agent-handoff",
"prepared-lifecycle",
"run-from-deployment",
@@ -27,6 +26,22 @@ describe("defense storyboard catalog", () => {
"evaluation",
"conclusion",
]);
expect(findScene("architecture")?.beats.map((beat) => beat.id)).toEqual([
"overview",
"client",
"api",
"runtime",
]);
expect(findScene("prepared-lifecycle")?.beats.map((beat) => beat.id)).toEqual([
"discover",
"draft",
"diagnose",
"repair",
"artifact",
"deployment",
]);
expect(findScene("conclusion")?.number).toBe(13);
expect(findScene("authoring")).toBeUndefined();
for (const scene of mainScenes) {
expect(scene.beats.length).toBeGreaterThan(0);
expect(new Set(scene.beats.map((beat) => beat.id)).size).toBe(scene.beats.length);
@@ -51,7 +66,8 @@ describe("defense storyboard catalog", () => {
it("keeps chat out of the way during proof-heavy demo beats", () => {
expect(findBeat("prepared-lifecycle", "discover")?.chatMode).toBe("hidden");
expect(findBeat("prepared-lifecycle", "draft")?.chatMode).toBe("hidden");
expect(findBeat("prepared-lifecycle", "validate")?.chatMode).toBe("hidden");
expect(findBeat("prepared-lifecycle", "diagnose")?.chatMode).toBe("hidden");
expect(findBeat("prepared-lifecycle", "repair")?.chatMode).toBe("hidden");
expect(findBeat("prepared-lifecycle", "artifact")?.chatMode).toBe("hidden");
expect(findBeat("prepared-lifecycle", "deployment")?.chatMode).toBe("hidden");
expect(findBeat("run-from-deployment", "input")?.chatMode).toBe("hidden");
@@ -63,29 +79,32 @@ describe("defense storyboard catalog", () => {
});
it("splits the demo climax into lifecycle, run, interrupt, and evidence scenes", () => {
expect(findScene("prepared-lifecycle")?.number).toBe(9);
expect(findScene("run-from-deployment")?.number).toBe(10);
expect(findScene("typed-human-boundary")?.number).toBe(11);
expect(findScene("resume-output-evidence")?.number).toBe(12);
expect(findScene("evaluation")?.number).toBe(13);
expect(findScene("conclusion")?.number).toBe(14);
expect(findScene("agent-handoff")?.number).toBe(7);
expect(findScene("prepared-lifecycle")?.number).toBe(8);
expect(findScene("run-from-deployment")?.number).toBe(9);
expect(findScene("typed-human-boundary")?.number).toBe(10);
expect(findScene("resume-output-evidence")?.number).toBe(11);
expect(findScene("evaluation")?.number).toBe(12);
expect(findScene("conclusion")?.number).toBe(13);
});
it("defines the lifecycle story beats before run evidence", () => {
expect(findBeat("prepared-lifecycle", "discover")?.caption).toMatch(/sources|capabilities|schemas/i);
expect(findBeat("prepared-lifecycle", "draft")?.caption).toMatch(/draft/i);
expect(findBeat("prepared-lifecycle", "validate")?.caption).toMatch(/diagnose|repair/i);
expect(findBeat("prepared-lifecycle", "diagnose")?.caption).toMatch(/diagnostic|missing-output/i);
expect(findBeat("prepared-lifecycle", "repair")?.caption).toMatch(/repair|valid Draft/i);
expect(findBeat("prepared-lifecycle", "artifact")?.caption).toMatch(/compile|artifact/i);
expect(findBeat("prepared-lifecycle", "deployment")?.caption).toMatch(/deploy|bindings/i);
});
it("keeps Scene 5 as vocabulary and moves applied lifecycle evidence to Scene 9", () => {
it("keeps Scene 5 as vocabulary and moves applied lifecycle evidence to Scene 8", () => {
expect(findBeat("lifecycle", "draft")?.caption).toMatch(/^Draft is mutable authoring state\.$/);
expect(findBeat("lifecycle", "artifact")?.caption).toMatch(/^Artifact is an immutable workflow definition\.$/);
expect(findBeat("lifecycle", "deployment")?.caption).toMatch(/^Deployment binds an artifact version/);
expect(findBeat("lifecycle", "run")?.caption).toMatch(/^Run records one execution/);
expect(findBeat("prepared-lifecycle", "validate")?.caption).toMatch(/incomplete|repair/i);
expect(findBeat("prepared-lifecycle", "deployment")?.caption).toMatch(/ready|does not run|Scene 10/i);
expect(findBeat("prepared-lifecycle", "diagnose")?.caption).toMatch(/diagnostic|missing-output/i);
expect(findBeat("prepared-lifecycle", "repair")?.caption).toMatch(/repair|valid Draft/i);
expect(findBeat("prepared-lifecycle", "deployment")?.caption).toMatch(/ready|does not run|Scene 9/i);
expect(findBeat("prepared-lifecycle", "deployment")?.caption).toMatch(/three-node|implementation extension/i);
});
+23 -28
View File
@@ -9,7 +9,6 @@ export type SceneView =
| "boundary"
| "lifecycle"
| "architecture"
| "authoring"
| "agent"
| "demo"
| "demo-lifecycle"
@@ -136,26 +135,11 @@ export const mainScenes = defineScenes([
sceneBeat("client", "Client operations", "Human and agent clients use the same public lifecycle surface.", { figure: { catalogId: "system-architecture", focusPath: [], activeNodeId: "client-operations" } }),
sceneBeat("api", "Transport and API", "JSON-RPC reaches WorkflowApi without owning domain behavior.", { figure: { catalogId: "system-architecture", focusPath: ["application-lifecycle"], activeNodeId: "workflow-api-boundary" } }),
sceneBeat("runtime", "Runtime and providers", "The runtime resolves provider-neutral capabilities and stores lifecycle records.", { figure: { catalogId: "system-architecture", focusPath: ["runtime-providers"], activeNodeId: "configured-providers" } }),
sceneBeat("node-use", "NodeUse", "One callable node validates input, invokes a capability, and reduces output into state.", { evidencePresentation: "receipt", figure: { catalogId: "system-architecture", focusPath: ["node-use"], activeNodeId: "node-def-handler" } }),
],
},
{
id: "authoring",
number: 7,
title: "Author, Validate, Repair",
claimClass: "implemented",
evidencePointer: "CLI documentation; draft authoring API; challenge UX findings",
view: "authoring",
beats: [
sceneBeat("discover", "Discover", "This authoring loop operates on the mutable Draft: an external agent proposal becomes a valid workflow through discover, author, diagnose, and repair. Artifact, Deployment, and Run follow after validation."),
sceneBeat("author", "Author", "This authoring loop operates on the mutable Draft: an external agent proposal becomes a valid workflow through discover, author, diagnose, and repair. Artifact, Deployment, and Run follow after validation."),
sceneBeat("diagnose", "Diagnose", "This authoring loop operates on the mutable Draft: an external agent proposal becomes a valid workflow through discover, author, diagnose, and repair. Artifact, Deployment, and Run follow after validation.", { evidencePresentation: "receipt" }),
sceneBeat("repair", "Repair", "This authoring loop operates on the mutable Draft: an external agent proposal becomes a valid workflow through discover, author, diagnose, and repair. Artifact, Deployment, and Run follow after validation."),
],
},
{
id: "agent-handoff",
number: 8,
number: 7,
title: "Agent Request",
claimClass: "implemented",
evidencePointer: "Constrained demo agent and prepared replay recipe",
@@ -167,7 +151,7 @@ export const mainScenes = defineScenes([
},
{
id: "prepared-lifecycle",
number: 9,
number: 8,
title: "Prepared Workflow Lifecycle",
claimClass: "implemented",
evidencePointer: "examples/lda_report_workflow; deployment inspect replay evidence",
@@ -175,14 +159,25 @@ export const mainScenes = defineScenes([
beats: [
sceneBeat("discover", "Discover capabilities", "The later issue-review example inspects configured sources, capabilities, and schemas.", { chatMode: "hidden", chatTheme: "light" }),
sceneBeat("draft", "Author draft", "Create and edit a Draft for report generation before execution.", { chatMode: "hidden", chatTheme: "light" }),
sceneBeat("validate", "Validate and repair", "Validate incomplete state, diagnose a missing binding, and apply a targeted repair.", { chatMode: "hidden", chatTheme: "light" }),
sceneBeat(
"diagnose",
"Diagnose invalid draft",
"Validation returns a structured missing-output diagnostic before artifact creation.",
{ chatMode: "hidden", chatTheme: "light" },
),
sceneBeat(
"repair",
"Apply targeted repair",
"A focused output-map edit resolves the diagnostic and produces a valid Draft.",
{ chatMode: "hidden", chatTheme: "light" },
),
sceneBeat("artifact", "Compile artifact", "Save the validated plan as an immutable artifact.", { chatMode: "hidden", chatTheme: "light" }),
sceneBeat("deployment", "Deploy and validate", "Bind and validate a ready Deployment; the run begins in Scene 10. This implementation extension is richer than the thesis three-node case study.", { chatMode: "hidden", chatTheme: "light" }),
sceneBeat("deployment", "Deploy and validate", "Bind and validate a ready Deployment; the run begins in Scene 9. This implementation extension is richer than the thesis three-node case study.", { chatMode: "hidden", chatTheme: "light" }),
],
},
{
id: "run-from-deployment",
number: 10,
number: 9,
title: "Run From Deployment",
claimClass: "implemented",
evidencePointer: "workflow.runs.start replay evidence",
@@ -195,7 +190,7 @@ export const mainScenes = defineScenes([
},
{
id: "typed-human-boundary",
number: 11,
number: 10,
title: "Typed Human Boundary",
claimClass: "implemented",
evidencePointer: "typed interrupt payload and resume contract",
@@ -212,7 +207,7 @@ export const mainScenes = defineScenes([
},
{
id: "resume-output-evidence",
number: 12,
number: 11,
title: "Resume, Output, Evidence",
claimClass: "implemented",
evidencePointer: "workflow.runs.resume, workflow output, and trace replay evidence",
@@ -225,7 +220,7 @@ export const mainScenes = defineScenes([
},
{
id: "evaluation",
number: 13,
number: 12,
title: "Evaluation",
claimClass: "evaluated",
evidencePointer: "Thesis Evaluation and Appendix C",
@@ -238,7 +233,7 @@ export const mainScenes = defineScenes([
},
{
id: "conclusion",
number: 14,
number: 13,
title: "Limits and Conclusion",
claimClass: "future-work",
evidencePointer: "Thesis Limitations, Future Work, and Conclusion",
@@ -405,7 +400,7 @@ export const discussionBranches = defineDiscussionBranches([
},
{
id: "raw-plan-import",
parentSceneId: "authoring",
parentSceneId: "prepared-lifecycle",
title: "Raw plan import",
claimClass: "implemented",
evidencePointer: "Thesis Authoring; raw plan import and compilation",
@@ -413,7 +408,7 @@ export const discussionBranches = defineDiscussionBranches([
},
{
id: "validation-diagnostics",
parentSceneId: "authoring",
parentSceneId: "prepared-lifecycle",
title: "Validation and diagnostics",
claimClass: "implemented",
evidencePointer: "Thesis Validation; diagnostic repair hints",
@@ -421,7 +416,7 @@ export const discussionBranches = defineDiscussionBranches([
},
{
id: "why-schemas",
parentSceneId: "authoring",
parentSceneId: "prepared-lifecycle",
title: "Why schemas matter",
claimClass: "implemented",
evidencePointer: "wf schema command; draft validation diagnostics; typed interrupt contracts",