feat: add neutral architecture overview beat

This commit is contained in:
lda
2026-07-13 10:24:42 +07:00 Verified
parent 870902a69b
commit aec2651ae6
12 changed files with 37 additions and 14 deletions
@@ -75,6 +75,7 @@ afterEach(() => {
describe("PresentationRoute", () => {
const directHashRoutes = [
{ hash: "#scene/thesis/title", heading: "Design and Implementation of lda.chat", hasDemoChrome: false },
{ hash: "#scene/architecture/overview", heading: "Architecture Zoom", hasDemoChrome: false },
{ hash: "#scene/architecture/client", heading: "Architecture Zoom", hasDemoChrome: false },
{ hash: "#scene/authoring/diagnose", heading: "Author, Validate, Repair", hasDemoChrome: false },
{
@@ -148,6 +148,7 @@ const beatContracts = {
"thesis/substrate": { mode: "split", primarySurface: "opening-decomposition", supportSurface: "none" },
"problem/direct-actions": { mode: "split", primarySurface: "tool-loop-transcript", supportSurface: "workflow-blueprint" },
"problem/missing-contracts": { mode: "split", primarySurface: "workflow-blueprint", supportSurface: "tool-loop-transcript" },
"architecture/overview": { mode: "focal", primarySurface: "interactive-architecture", supportSurface: "none" },
"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" },
@@ -368,7 +368,7 @@
.architecture-scene .interactive-figure:has(.figure-node[data-active="true"])
.figure-node:not([data-active="true"]) {
opacity: 0.48;
opacity: 0.76;
}
.architecture-scene .figure-node[data-active="true"] {
@@ -15,7 +15,7 @@ describe("PresenterRoute", () => {
expect(screen.getByRole("main", { name: /lda.chat presenter notes/i })).toBeInTheDocument();
expect(screen.getByText(/This project began with the goal/i)).toBeInTheDocument();
expect(screen.getByText("the system underneath the chat").tagName).toBe("STRONG");
expect(screen.getByRole("navigation", { name: /presenter note navigation/i })).toHaveTextContent("1 / 42");
expect(screen.getByRole("navigation", { name: /presenter note navigation/i })).toHaveTextContent("1 / 43");
expect(screen.getByRole("link", { name: "Next →" })).toHaveAttribute("href", "#scene/thesis/substrate");
expect(screen.getByRole("link", { name: /open audience slide/i })).toHaveAttribute("href", "/present#scene/thesis/title");
expect(screen.queryByText(/live target/i)).not.toBeInTheDocument();
@@ -154,34 +154,41 @@ export const presenterNotes = [
["Thesis Workflow Lifecycle"],
{ qnaBranchIds: ["lifecycle-states", "run-persistence"] },
),
beatNote(
"architecture",
"overview",
7,
"First, the **implemented architecture spine** and its ownership boundaries.",
["Thesis System Architecture", "docs/project_map.md"],
),
beatNote(
"architecture",
"client",
13,
"Human operators and external agents enter through **the same public lifecycle surface**.",
10,
"Humans and agents share **one public lifecycle surface**.",
["Thesis System Architecture", "docs/project_map.md"],
),
beatNote(
"architecture",
"api",
13,
"**WorkflowApi owns lifecycle operations**; JSON-RPC adapts requests without owning domain behavior.",
11,
"WorkflowApi owns lifecycle operations; **JSON-RPC only adapts transport**.",
["Thesis System Architecture", "docs/source_architecture.md"],
{ qnaBranchIds: ["not-just-cli"] },
),
beatNote(
"architecture",
"runtime",
14,
"**WorkflowServer composes records, provider-neutral capabilities, WorkflowApi, and the execution kernel**; provider behavior remains outside the core.",
13,
"WorkflowServer composes **records, capabilities, API, and kernel**; providers remain outside the core.",
["Thesis System Architecture", "docs/source_architecture.md"],
{ qnaBranchIds: ["provider-security"] },
),
beatNote(
"architecture",
"node-use",
15,
"A NodeUse resolves bindings, **invokes its NodeDef handler**, reduces output into state, appends a trace frame, and routes the outcome.",
14,
"NodeUse **invokes a NodeDef handler**, reduces state, records trace, and routes the declared outcome.",
["Thesis Workflow Core Model"],
),
beatNote(
@@ -71,6 +71,17 @@ const renderArchitecture = (overrides: Partial<React.ComponentProps<typeof Archi
afterEach(() => cleanup());
describe("ArchitectureScene", () => {
it("keeps the overview beat neutral so the entire spine remains readable", () => {
renderArchitecture({
beat: { ...mockBeat, id: "overview" },
focusPath: [],
activeNodeId: null,
});
expect(screen.getByTestId("architecture-scene")).toHaveAttribute("data-architecture-beat", "overview");
expect(document.querySelector('.figure-node[data-active="true"]')).toBeNull();
});
it("renders the architecture spine and expands the capability boundary", () => {
const onFocusPathChange = vi.fn();
renderArchitecture({ focusPath: [], onFocusPathChange });
@@ -132,6 +132,7 @@ export const mainScenes = defineScenes([
evidencePointer: "Thesis System Architecture; docs/project_map.md; docs/source_architecture.md",
view: "architecture",
beats: [
sceneBeat("overview", "Architecture spine", "The implemented system separates its public surface, lifecycle records, provider boundary, and execution kernel.", { figure: { catalogId: "system-architecture", focusPath: [], activeNodeId: null } }),
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" } }),