feat: reframe presentation opening as agent roles

This commit is contained in:
lda
2026-07-12 00:07:30 +07:00 Verified
parent 3aaf70b89c
commit ddbcb7a0ae
5 changed files with 65 additions and 41 deletions
@@ -53,7 +53,7 @@ const renderSceneBodyAtMainLocation = (sceneId: MainLocation["sceneId"], beatId:
); );
describe("SceneBody", () => { describe("SceneBody", () => {
it("renders Scene 1 as an opening decomposition visual", () => { it("renders Scene 1 as an agent-shaped contribution visual", () => {
const location: PresentationLocation = { kind: "main", sceneId: "thesis", beatId: "substrate", focusPath: [] }; const location: PresentationLocation = { kind: "main", sceneId: "thesis", beatId: "substrate", focusPath: [] };
render( render(
@@ -71,10 +71,10 @@ describe("SceneBody", () => {
expect(screen.getByRole("region", { name: "thesis opening" })).toHaveAttribute( expect(screen.getByRole("region", { name: "thesis opening" })).toHaveAttribute(
"data-opening-focus", "data-opening-focus",
"substrate", "contribution",
); );
expect(screen.getByText("submitted substrate")).toBeInTheDocument(); expect(screen.getByText("Runner / platform")).toBeInTheDocument();
expect(screen.getByText("Typed · Durable · Inspectable")).toBeInTheDocument(); expect(screen.getByText("Implemented contribution")).toBeInTheDocument();
expect(screen.getByRole("button", { name: /where is the ai agent/i })).toBeInTheDocument(); expect(screen.getByRole("button", { name: /where is the ai agent/i })).toBeInTheDocument();
}); });
@@ -34,4 +34,15 @@ describe("ConceptPrimitives", () => {
expect(screen.getByText("Design")).toBeInTheDocument(); expect(screen.getByText("Design")).toBeInTheDocument();
expect(screen.getByText("Run")).toBeInTheDocument(); expect(screen.getByText("Run")).toBeInTheDocument();
}); });
it("keeps an optional scene-specific class on a concept rail", () => {
render(
<ConceptRail label="Agent roles" className="opening-thesis__agent-system">
<ConceptNode title="Planner" icon="planner" />
</ConceptRail>,
);
expect(screen.getByRole("group", { name: "Agent roles" }))
.toHaveClass("opening-thesis__agent-system");
});
}); });
@@ -68,10 +68,11 @@ export const ConceptNode = ({
type ConceptRailProps = { type ConceptRailProps = {
readonly label: string; readonly label: string;
readonly children: ReactNode; readonly children: ReactNode;
readonly className?: string | undefined;
}; };
export const ConceptRail = ({ label, children }: ConceptRailProps) => ( export const ConceptRail = ({ label, children, className }: ConceptRailProps) => (
<div className="concept-rail" role="group" aria-label={label}> <div className={["concept-rail", className].filter(Boolean).join(" ")} role="group" aria-label={label}>
{children} {children}
</div> </div>
); );
@@ -8,31 +8,38 @@ const thesisScene = findScene("thesis")!;
afterEach(() => cleanup()); afterEach(() => cleanup());
describe("OpeningThesisScene", () => { describe("OpeningThesisScene", () => {
it("makes the title boundary the opening focal artifact", () => { it("introduces the agent-shaped product goal", () => {
render(<OpeningThesisScene scene={thesisScene} beat={findBeat("thesis", "title")!} />); render(<OpeningThesisScene scene={thesisScene} beat={findBeat("thesis", "title")!} />);
const opening = screen.getByRole("region", { name: /thesis opening/i }); const opening = screen.getByRole("region", { name: /thesis opening/i });
expect(opening).toHaveAttribute("data-opening-focus", "title"); expect(opening).toHaveAttribute("data-opening-focus", "title");
expect(opening).toHaveAttribute("data-support-state", "receded");
expect(screen.getByRole("heading", { name: /Design and Implementation of lda\.chat/i })).toBeInTheDocument(); expect(screen.getByRole("heading", { name: /Design and Implementation of lda\.chat/i })).toBeInTheDocument();
expect(screen.getByRole("heading", { name: "An AI Agent for Workspace Workflows" })).toBeInTheDocument();
const roles = screen.getByRole("group", { name: "AI agent roles" });
expect(roles).toHaveClass("opening-thesis__agent-system");
expect(roles.querySelectorAll("[data-concept-emphasis]")).toHaveLength(3);
expect(screen.getByText("Planner")).toBeInTheDocument(); expect(screen.getByText("Planner")).toBeInTheDocument();
expect(screen.getByText("Tool Surface")).toBeInTheDocument(); expect(screen.getByText("Tool surface")).toBeInTheDocument();
expect(screen.getByText("Workflow Platform")).toBeInTheDocument(); expect(screen.getByText("Runner / platform")).toBeInTheDocument();
expect(screen.queryByRole("heading", { name: "Thesis" })).not.toBeInTheDocument();
expect(screen.queryByText("Decomposed")).not.toBeInTheDocument();
expect(screen.getByRole("img", { name: /Planner icon/i })).toBeInTheDocument(); expect(screen.getByRole("img", { name: /Planner icon/i })).toBeInTheDocument();
expect(screen.getByRole("img", { name: /Tool Surface icon/i })).toBeInTheDocument(); expect(screen.getByRole("img", { name: /Tool surface icon/i })).toBeInTheDocument();
expect(screen.getByRole("img", { name: /Workflow Platform icon/i })).toBeInTheDocument(); expect(screen.getByRole("img", { name: /Runner \/ platform icon/i })).toBeInTheDocument();
}); });
it("renders contribution focus without relying on lda.chat as category label", () => { it("identifies runner and platform as the implemented contribution", () => {
render(<OpeningThesisScene scene={thesisScene} beat={findBeat("thesis", "substrate")!} />); render(<OpeningThesisScene scene={thesisScene} beat={findBeat("thesis", "substrate")!} />);
const opening = screen.getByRole("region", { name: /thesis opening/i }); const opening = screen.getByRole("region", { name: /thesis opening/i });
expect(opening).toHaveAttribute("data-opening-focus", "substrate"); expect(opening).toHaveAttribute("data-opening-focus", "contribution");
expect(opening).toHaveAttribute("data-support-state", "revealed"); expect(screen.getByText("Codex, Claude, OpenCode")).toBeInTheDocument();
expect(screen.getByText("Codex / Claude / OpenCode")).toBeInTheDocument(); expect(screen.getByText("CLI, MCP, JSON-RPC")).toBeInTheDocument();
expect(screen.getByText("CLI / MCP / APIs")).toBeInTheDocument(); expect(screen.getByText("Implemented contribution")).toBeInTheDocument();
expect(screen.getByText("submitted substrate")).toBeInTheDocument(); expect(screen.getByText("Lifecycle, validation, records, traces, and interrupt/resume")).toBeInTheDocument();
expect(screen.getByText("Typed · Durable · Inspectable")).toBeInTheDocument(); expect(screen.getByText("Planner")).toBeInTheDocument();
expect(screen.getByText("Tool surface")).toBeInTheDocument();
expect(screen.getByText("Runner / platform")).toBeInTheDocument();
expect(screen.queryByText("wf")).not.toBeInTheDocument(); expect(screen.queryByText("wf")).not.toBeInTheDocument();
}); });
}); });
@@ -13,41 +13,46 @@ export const OpeningThesisScene = ({ scene, beat }: OpeningThesisSceneProps) =>
const contributionBeat = beat.id === "substrate"; const contributionBeat = beat.id === "substrate";
return ( return (
<> <>
<StageCaption eyebrow="Origin story" title={title}> <section
className="opening-thesis-scene"
aria-label="thesis opening"
data-opening-focus={contributionBeat ? "contribution" : "title"}
>
<StageCaption eyebrow="Title" title={title}>
<p>{beat.caption}</p> <p>{beat.caption}</p>
</StageCaption> </StageCaption>
<section <div
className="opening-thesis" className="opening-thesis"
aria-label="thesis opening"
data-opening-beat={beat.id} data-opening-beat={beat.id}
data-opening-focus={contributionBeat ? "substrate" : "title"} data-opening-focus={contributionBeat ? "contribution" : "title"}
data-support-state={contributionBeat ? "revealed" : "receded"}
> >
<div className="opening-thesis__title-card" data-opening-role="title"> <header className="opening-thesis__statement">
<span>AI agent for workspace workflows</span> <p>Product goal</p>
<strong>{contributionBeat ? "Decomposed" : scene.title}</strong> <h2>An AI Agent for Workspace Workflows</h2>
</div> </header>
<div className="opening-thesis__decomposition"> <ConceptRail label="AI agent roles" className="opening-thesis__agent-system">
<ConceptRail label="AI agent components">
<ConceptNode <ConceptNode
title="Planner" title="Planner"
subtitle="Codex / Claude / OpenCode" subtitle="Codex, Claude, OpenCode"
icon="planner" icon="planner"
emphasis={contributionBeat ? "muted" : "normal"}
/> />
<ConceptNode <ConceptNode
title="Tool Surface" title="Tool surface"
subtitle="CLI / MCP / APIs" subtitle="CLI, MCP, JSON-RPC"
icon="tool" icon="tool"
emphasis={contributionBeat ? "muted" : "normal"}
/> />
<ConceptNode <ConceptNode
title="Workflow Platform" title="Runner / platform"
subtitle="submitted substrate" subtitle="Workflow lifecycle and deterministic execution"
icon="platform" icon="platform"
emphasis="primary" emphasis={contributionBeat ? "primary" : "normal"}
> >
<span>Typed · Durable · Inspectable</span> {contributionBeat ? (
<>
<span>Implemented contribution</span>
<span>Lifecycle, validation, records, traces, and interrupt/resume</span>
</>
) : null}
</ConceptNode> </ConceptNode>
</ConceptRail> </ConceptRail>
</div> </div>