fix: close final Scene 8 review findings
This commit is contained in:
@@ -34,8 +34,8 @@ can be shown after selecting replay with the runbook's session-storage switch.
|
|||||||
| `agent-handoff/request` | I will now show a prepared demonstration built on this platform. The chat is a presentation interface, not the autonomous planner evaluated by the thesis. The chat translates a report request into the same public lifecycle operations an external agent could call. This prepared path demonstrates product behavior and recorded evidence, not a fresh model-performance result. | Agent request surface | Workflow substrate framing | hidden | replay-only; Constrained demo agent and prepared replay recipe | `agent-handoff/request` |
|
| `agent-handoff/request` | I will now show a prepared demonstration built on this platform. The chat is a presentation interface, not the autonomous planner evaluated by the thesis. The chat translates a report request into the same public lifecycle operations an external agent could call. This prepared path demonstrates product behavior and recorded evidence, not a fresh model-performance result. | Agent request surface | Workflow substrate framing | hidden | replay-only; Constrained demo agent and prepared replay recipe | `agent-handoff/request` |
|
||||||
| `prepared-lifecycle/discover` | It inspects sources, capabilities, and schemas rather than guessing at hidden interfaces. | Prepared lifecycle: discovery | Capability/schema evidence | hidden | replay-only; `examples/lda_report_workflow`; deployment inspect replay evidence | `prepared-lifecycle/discover` |
|
| `prepared-lifecycle/discover` | It inspects sources, capabilities, and schemas rather than guessing at hidden interfaces. | Prepared lifecycle: discovery | Capability/schema evidence | hidden | replay-only; `examples/lda_report_workflow`; deployment inspect replay evidence | `prepared-lifecycle/discover` |
|
||||||
| `prepared-lifecycle/draft` | Focused operations modify mutable authoring state before execution. | Prepared lifecycle: draft | Workflow definition | hidden | replay-only; `examples/lda_report_workflow`; deployment inspect replay evidence | `prepared-lifecycle/draft` |
|
| `prepared-lifecycle/draft` | Focused operations modify mutable authoring state before execution. | Prepared lifecycle: draft | Workflow definition | hidden | replay-only; `examples/lda_report_workflow`; deployment inspect replay evidence | `prepared-lifecycle/draft` |
|
||||||
| `prepared-lifecycle/diagnose` | Structured diagnostics identify the missing output projection. | Diagnostic receipt | Draft authoring surface | hidden | replay-only; `examples/lda_report_workflow`; deployment inspect replay evidence | `prepared-lifecycle/diagnose` |
|
| `prepared-lifecycle/diagnose` | Revision 2 is valid; this prepared fault injection, not an accidental discovery, runs `wf draft remove-route lda_report_workflow --revision 2 --step analyze --outcome ok`, producing invalid revision 3 and `missing_outcome_edge`. | Diagnostic receipt | Draft authoring surface | hidden | replay-only; reviewed prepared authoring evidence | `prepared-lifecycle/diagnose` |
|
||||||
| `prepared-lifecycle/repair` | One focused output-map edit resolves it; hints do not guarantee automatic repair. | Repair guidance | Diagnostic receipt | hidden | replay-only; `examples/lda_report_workflow`; deployment inspect replay evidence | `prepared-lifecycle/repair` |
|
| `prepared-lifecycle/repair` | The existing `wf draft set-route lda_report_workflow --revision 3 --step analyze --outcome ok --to __end__` command repairs the route removal and produces valid revision 4. | Repair guidance | Diagnostic receipt | hidden | replay-only; reviewed prepared authoring evidence | `prepared-lifecycle/repair` |
|
||||||
| `prepared-lifecycle/artifact` | It saves the validated plan as immutable artifact lda_report_case_study version 1. | Prepared lifecycle: artifact | Lifecycle state | hidden | replay-only; `examples/lda_report_workflow`; deployment inspect replay evidence | `prepared-lifecycle/artifact` |
|
| `prepared-lifecycle/artifact` | It saves the validated plan as immutable artifact lda_report_case_study version 1. | Prepared lifecycle: artifact | Lifecycle state | hidden | replay-only; `examples/lda_report_workflow`; deployment inspect replay evidence | `prepared-lifecycle/artifact` |
|
||||||
| `prepared-lifecycle/deployment` | Deployment binds and validates three local sources; execution starts in the next scene. | Prepared lifecycle: deployment | Binding/readiness evidence | hidden | replay-only; `examples/lda_report_workflow`; deployment inspect replay evidence | `prepared-lifecycle/deployment` |
|
| `prepared-lifecycle/deployment` | Deployment binds and validates three local sources; execution starts in the next scene. | Prepared lifecycle: deployment | Binding/readiness evidence | hidden | replay-only; `examples/lda_report_workflow`; deployment inspect replay evidence | `prepared-lifecycle/deployment` |
|
||||||
| `run-from-deployment/input` | The deployment receives selected local documents and an issue-board path. | Workflow input panel | Prepared deployment | hidden | live-capable; `workflow.runs.start` replay evidence | `prepared-lifecycle/deployment` |
|
| `run-from-deployment/input` | The deployment receives selected local documents and an issue-board path. | Workflow input panel | Prepared deployment | hidden | live-capable; `workflow.runs.start` replay evidence | `prepared-lifecycle/deployment` |
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ end-to-end run.
|
|||||||
|
|
||||||
### Scene 8 — Prepared Workflow Lifecycle
|
### Scene 8 — Prepared Workflow Lifecycle
|
||||||
- Audience takeaway: The request becomes six concise authoring stages: Discover, Draft, Diagnose, Repair, Artifact, and Deployment.
|
- Audience takeaway: The request becomes six concise authoring stages: Discover, Draft, Diagnose, Repair, Artifact, and Deployment.
|
||||||
- Visible proof: The phase rail, staged messages, structured diagnostic, focused output-map edit, and changing factual evidence advance across all six beats.
|
- Visible proof: Draft revision 2 is valid with `analyze.ok -> __end__`; the transcript explicitly labels a prepared fault injection, not an accidental discovery, using `wf draft remove-route lda_report_workflow --revision 2 --step analyze --outcome ok`, then shows invalid revision 3 with `missing_outcome_edge` and repairs it with the existing `wf draft set-route lda_report_workflow --revision 3 --step analyze --outcome ok --to __end__` command to valid revision 4.
|
||||||
- Missing or confusing: Deployment binds and validates three local sources but does not execute; that boundary needs an explicit spoken pause.
|
- Missing or confusing: Deployment binds and validates three local sources but does not execute; that boundary needs an explicit spoken pause.
|
||||||
- Next action: keep
|
- Next action: keep
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ end-to-end run.
|
|||||||
- Scene 5 -> 6 works if Deployment is the handoff: lifecycle vocabulary becomes the architecture that owns it.
|
- Scene 5 -> 6 works if Deployment is the handoff: lifecycle vocabulary becomes the architecture that owns it.
|
||||||
- Scene 6 -> 7 works: architecture hands off to a bounded prepared request surface.
|
- Scene 6 -> 7 works: architecture hands off to a bounded prepared request surface.
|
||||||
- Scene 7 -> 8 works and is not a duplicate: request/discovery becomes staged lifecycle evidence.
|
- Scene 7 -> 8 works and is not a duplicate: request/discovery becomes staged lifecycle evidence.
|
||||||
- Scene 8 -> 9 is the critical boundary: Deployment prepares; Scene 9 alone starts execution. Keep the explicit no-run wording.
|
- Scene 8 -> 9 is the critical boundary: the prepared route-removal fault injection is repaired before Deployment; Deployment prepares, and Scene 9 alone starts execution. Keep the explicit no-run wording.
|
||||||
- Scene 9 -> 10 -> 11 works as one climax in replay, but the revision branch has a factual run-identity defect and the live path is blocked.
|
- Scene 9 -> 10 -> 11 works as one climax in replay, but the revision branch has a factual run-identity defect and the live path is blocked.
|
||||||
- Scene 12 -> 13 works: evaluation limits become the contribution and future-work close.
|
- Scene 12 -> 13 works: evaluation limits become the contribution and future-work close.
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ export type PreparedAuthoringToolName =
|
|||||||
| "workflow.draft_workspaces.create_from_capability"
|
| "workflow.draft_workspaces.create_from_capability"
|
||||||
| "workflow.draft_workspaces.add_step_from_capability"
|
| "workflow.draft_workspaces.add_step_from_capability"
|
||||||
| "workflow.draft_workspaces.get"
|
| "workflow.draft_workspaces.get"
|
||||||
|
| "workflow.draft_workspaces.remove_route"
|
||||||
| "workflow.draft_workspaces.validate"
|
| "workflow.draft_workspaces.validate"
|
||||||
| "workflow.draft_workspaces.set_route"
|
| "workflow.draft_workspaces.set_route"
|
||||||
| "workflow.draft_workspaces.compile"
|
| "workflow.draft_workspaces.compile"
|
||||||
|
|||||||
@@ -121,6 +121,9 @@ describe("PresentationRoute", () => {
|
|||||||
expect(within(result).getByText("missing_outcome_edge")).toBeInTheDocument();
|
expect(within(result).getByText("missing_outcome_edge")).toBeInTheDocument();
|
||||||
expect(within(result).getByText("nodes[analyze]")).toBeInTheDocument();
|
expect(within(result).getByText("nodes[analyze]")).toBeInTheDocument();
|
||||||
expect(within(result).getByText(/missing edges for outcomes.*ok/i)).toBeInTheDocument();
|
expect(within(result).getByText(/missing edges for outcomes.*ok/i)).toBeInTheDocument();
|
||||||
|
expect(within(result).getByRole("note", { name: /prepared fault injection/i })).toHaveTextContent(
|
||||||
|
"wf draft remove-route lda_report_workflow --revision 2 --step analyze --outcome ok",
|
||||||
|
);
|
||||||
expect(screen.queryByText(/missing output projection/i)).not.toBeInTheDocument();
|
expect(screen.queryByText(/missing output projection/i)).not.toBeInTheDocument();
|
||||||
}, 15000);
|
}, 15000);
|
||||||
|
|
||||||
@@ -139,6 +142,16 @@ describe("PresentationRoute", () => {
|
|||||||
expect(within(result).getByText("0 diagnostics", { exact: true })).toBeInTheDocument();
|
expect(within(result).getByText("0 diagnostics", { exact: true })).toBeInTheDocument();
|
||||||
}, 15000);
|
}, 15000);
|
||||||
|
|
||||||
|
it("routes Diagnose to a bounded result scrollport on narrow canvases", async () => {
|
||||||
|
window.location.hash = "#scene/prepared-lifecycle/diagnose";
|
||||||
|
const { PresentationRoute } = await import("./PresentationRoute.js");
|
||||||
|
render(<PresentationRoute />);
|
||||||
|
|
||||||
|
const result = await screen.findByRole("region", { name: "draft validation diagnostic" });
|
||||||
|
expect(result).toHaveAttribute("data-scrollport", "bounded-result");
|
||||||
|
expect(result).toHaveAttribute("data-scroll-bound", "viewport-relative");
|
||||||
|
}, 15000);
|
||||||
|
|
||||||
it("exposes an application-owned readiness signal for rehearsal capture", async () => {
|
it("exposes an application-owned readiness signal for rehearsal capture", async () => {
|
||||||
window.location.hash = "#scene/thesis/title";
|
window.location.hash = "#scene/thesis/title";
|
||||||
const { PresentationRoute } = await import("./PresentationRoute.js");
|
const { PresentationRoute } = await import("./PresentationRoute.js");
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ describe("AuthoringConversation", () => {
|
|||||||
|
|
||||||
const log = screen.getByRole("log", { name: "prepared authoring conversation" });
|
const log = screen.getByRole("log", { name: "prepared authoring conversation" });
|
||||||
expect(log).toHaveAttribute("data-surface", "dock");
|
expect(log).toHaveAttribute("data-surface", "dock");
|
||||||
expect(screen.getByRole("button", { name: /validate.*2 tool calls/i }))
|
expect(screen.getByRole("button", { name: /validate.*3 tool calls/i }))
|
||||||
.toHaveAttribute("aria-expanded", "true");
|
.toHaveAttribute("aria-expanded", "true");
|
||||||
expect(screen.getByRole("button", { name: /draft.*3 tool calls/i }))
|
expect(screen.getByRole("button", { name: /draft.*3 tool calls/i }))
|
||||||
.toHaveAttribute("aria-expanded", "false");
|
.toHaveAttribute("aria-expanded", "false");
|
||||||
|
|||||||
@@ -60,6 +60,9 @@ describe("AuthoringPhaseVisual", () => {
|
|||||||
expect(within(result).getByText(/missing edges for outcomes.*ok/i)).toBeInTheDocument();
|
expect(within(result).getByText(/missing edges for outcomes.*ok/i)).toBeInTheDocument();
|
||||||
expect(within(result).getByText(/cannot prove where execution goes next/i)).toBeInTheDocument();
|
expect(within(result).getByText(/cannot prove where execution goes next/i)).toBeInTheDocument();
|
||||||
expect(within(result).getByText("Revision 3")).toBeInTheDocument();
|
expect(within(result).getByText("Revision 3")).toBeInTheDocument();
|
||||||
|
expect(within(result).getByRole("note", { name: /prepared fault injection/i })).toHaveTextContent(
|
||||||
|
"wf draft remove-route lda_report_workflow --revision 2 --step analyze --outcome ok",
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renders route repair as a valid revision with compact prior context", () => {
|
it("renders route repair as a valid revision with compact prior context", () => {
|
||||||
|
|||||||
@@ -74,6 +74,8 @@ const ResultRoot = ({
|
|||||||
className={`authoring-visual authoring-result authoring-result--${kind}`}
|
className={`authoring-visual authoring-result authoring-result--${kind}`}
|
||||||
aria-label={label}
|
aria-label={label}
|
||||||
data-authoring-result={kind}
|
data-authoring-result={kind}
|
||||||
|
data-scrollport="bounded-result"
|
||||||
|
data-scroll-bound="viewport-relative"
|
||||||
data-presentation-surface="editorial"
|
data-presentation-surface="editorial"
|
||||||
data-visual-role="primary"
|
data-visual-role="primary"
|
||||||
>
|
>
|
||||||
@@ -152,6 +154,18 @@ const DiagnosticResult = ({ evidence }: { readonly evidence: EvidenceOf<"diagnos
|
|||||||
/>
|
/>
|
||||||
<p className="authoring-result__explanation">{evidence.diagnostic.explanation}</p>
|
<p className="authoring-result__explanation">{evidence.diagnostic.explanation}</p>
|
||||||
</div>
|
</div>
|
||||||
|
<aside
|
||||||
|
className="authoring-result__fault-injection"
|
||||||
|
role="note"
|
||||||
|
aria-label={evidence.faultInjection.label}
|
||||||
|
>
|
||||||
|
<span>{evidence.faultInjection.label}</span>
|
||||||
|
<code>{evidence.faultInjection.command}</code>
|
||||||
|
<p>
|
||||||
|
Revision {evidence.faultInjection.fromRevision} was valid; this prepared edit intentionally
|
||||||
|
produced invalid revision {evidence.faultInjection.toRevision} for diagnosis.
|
||||||
|
</p>
|
||||||
|
</aside>
|
||||||
</ResultRoot>
|
</ResultRoot>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -190,7 +190,7 @@ describe("PreparedAuthoringLifecycleScene", () => {
|
|||||||
|
|
||||||
expect(screen.getByRole("complementary", { name: /prepared authoring assistant/i }))
|
expect(screen.getByRole("complementary", { name: /prepared authoring assistant/i }))
|
||||||
.toHaveAttribute("data-phase", "diagnose");
|
.toHaveAttribute("data-phase", "diagnose");
|
||||||
expect(screen.getByRole("button", { name: /validate.*2 tool calls/i }))
|
expect(screen.getByRole("button", { name: /validate.*3 tool calls/i }))
|
||||||
.toHaveAttribute("aria-expanded", "true");
|
.toHaveAttribute("aria-expanded", "true");
|
||||||
expect(screen.getByRole("button", { name: /draft.*3 tool calls/i }))
|
expect(screen.getByRole("button", { name: /draft.*3 tool calls/i }))
|
||||||
.toHaveAttribute("aria-expanded", "false");
|
.toHaveAttribute("aria-expanded", "false");
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ describe("PresentationAssistantPane", () => {
|
|||||||
|
|
||||||
expect(screen.getByRole("button", { name: /artifact.*3 tool calls/i }))
|
expect(screen.getByRole("button", { name: /artifact.*3 tool calls/i }))
|
||||||
.toHaveAttribute("aria-expanded", "true");
|
.toHaveAttribute("aria-expanded", "true");
|
||||||
expect(screen.getByRole("button", { name: /validate.*2 tool calls/i }))
|
expect(screen.getByRole("button", { name: /validate.*3 tool calls/i }))
|
||||||
.toHaveAttribute("aria-expanded", "false");
|
.toHaveAttribute("aria-expanded", "false");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ describe("projectPreparedAuthoringPhase", () => {
|
|||||||
expect(phase.label).toBe("Discover");
|
expect(phase.label).toBe("Discover");
|
||||||
expect(phase.commands.length).toBeGreaterThanOrEqual(2);
|
expect(phase.commands.length).toBeGreaterThanOrEqual(2);
|
||||||
expect(phase.summary).toMatch(/sources|capabilities|schema/i);
|
expect(phase.summary).toMatch(/sources|capabilities|schema/i);
|
||||||
expect(phase.visual).toMatchObject({ kind: "inventory" });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("projects the draft phase with graph and routes", () => {
|
it("projects the draft phase with graph and routes", () => {
|
||||||
@@ -20,7 +19,6 @@ describe("projectPreparedAuthoringPhase", () => {
|
|||||||
expect(phase.label).toBe("Draft");
|
expect(phase.label).toBe("Draft");
|
||||||
expect(phase.commands.length).toBeGreaterThanOrEqual(2);
|
expect(phase.commands.length).toBeGreaterThanOrEqual(2);
|
||||||
expect(phase.summary).toMatch(/graph|routes/i);
|
expect(phase.summary).toMatch(/graph|routes/i);
|
||||||
expect(phase.visual).toMatchObject({ kind: "graph" });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("projects the validate phase with diagnosis and repair", () => {
|
it("projects the validate phase with diagnosis and repair", () => {
|
||||||
@@ -28,7 +26,6 @@ describe("projectPreparedAuthoringPhase", () => {
|
|||||||
expect(phase.label).toBe("Validate");
|
expect(phase.label).toBe("Validate");
|
||||||
expect(phase.commands.length).toBeGreaterThanOrEqual(2);
|
expect(phase.commands.length).toBeGreaterThanOrEqual(2);
|
||||||
expect(phase.summary).toMatch(/diagnos|repair/i);
|
expect(phase.summary).toMatch(/diagnos|repair/i);
|
||||||
expect(phase.visual).toMatchObject({ kind: "repair" });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("projects the artifact phase with immutable ID and version", () => {
|
it("projects the artifact phase with immutable ID and version", () => {
|
||||||
@@ -37,7 +34,6 @@ describe("projectPreparedAuthoringPhase", () => {
|
|||||||
expect(phase.commands.length).toBeGreaterThanOrEqual(2);
|
expect(phase.commands.length).toBeGreaterThanOrEqual(2);
|
||||||
expect(phase.summary).toMatch(/id/i);
|
expect(phase.summary).toMatch(/id/i);
|
||||||
expect(phase.summary).toMatch(/version/i);
|
expect(phase.summary).toMatch(/version/i);
|
||||||
expect(phase.visual).toMatchObject({ kind: "artifact" });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("projects the deployment phase with bindings and validation", () => {
|
it("projects the deployment phase with bindings and validation", () => {
|
||||||
@@ -45,7 +41,6 @@ describe("projectPreparedAuthoringPhase", () => {
|
|||||||
expect(phase.label).toBe("Deployment");
|
expect(phase.label).toBe("Deployment");
|
||||||
expect(phase.commands.length).toBeGreaterThanOrEqual(2);
|
expect(phase.commands.length).toBeGreaterThanOrEqual(2);
|
||||||
expect(phase.summary).toMatch(/bind|validat/i);
|
expect(phase.summary).toMatch(/bind|validat/i);
|
||||||
expect(phase.visual).toMatchObject({ kind: "bindings" });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("keeps the validation diagnostic and repair command distinct", () => {
|
it("keeps the validation diagnostic and repair command distinct", () => {
|
||||||
@@ -53,7 +48,14 @@ describe("projectPreparedAuthoringPhase", () => {
|
|||||||
const diagnosticCmd = phase.commands.find(
|
const diagnosticCmd = phase.commands.find(
|
||||||
(cmd) => cmd.result === "diagnostic" && cmd.detail?.includes("missing_outcome_edge"),
|
(cmd) => cmd.result === "diagnostic" && cmd.detail?.includes("missing_outcome_edge"),
|
||||||
);
|
);
|
||||||
|
const faultInjectionCmd = phase.commands.find(
|
||||||
|
(cmd) => cmd.title === "workflow.draft_workspaces.remove_route",
|
||||||
|
);
|
||||||
const repairCmd = phase.commands.find((cmd) => cmd.command.includes("draft set-route"));
|
const repairCmd = phase.commands.find((cmd) => cmd.command.includes("draft set-route"));
|
||||||
|
expect(faultInjectionCmd?.command).toBe(
|
||||||
|
"wf draft remove-route lda_report_workflow --revision 2 --step analyze --outcome ok",
|
||||||
|
);
|
||||||
|
expect(faultInjectionCmd?.detail).toMatch(/prepared fault injection/i);
|
||||||
expect(diagnosticCmd).toBeDefined();
|
expect(diagnosticCmd).toBeDefined();
|
||||||
expect(repairCmd).toBeDefined();
|
expect(repairCmd).toBeDefined();
|
||||||
expect(diagnosticCmd).not.toBe(repairCmd);
|
expect(diagnosticCmd).not.toBe(repairCmd);
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ export type AuthoringPhaseProjection = {
|
|||||||
readonly summary: string;
|
readonly summary: string;
|
||||||
readonly proof: readonly string[];
|
readonly proof: readonly string[];
|
||||||
readonly commands: readonly PreparedAuthoringCommand[];
|
readonly commands: readonly PreparedAuthoringCommand[];
|
||||||
readonly visual: AuthoringPhaseVisualModel;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type PreparedLifecycleStepProjection = AuthoringPhaseProjection & {
|
export type PreparedLifecycleStepProjection = AuthoringPhaseProjection & {
|
||||||
@@ -30,89 +29,6 @@ export type PreparedLifecycleStepProjection = AuthoringPhaseProjection & {
|
|||||||
readonly evidence: ReviewedAuthoringEvidence;
|
readonly evidence: ReviewedAuthoringEvidence;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AuthoringPhaseVisualModel =
|
|
||||||
| {
|
|
||||||
readonly kind: "inventory";
|
|
||||||
readonly sources: readonly string[];
|
|
||||||
readonly capability: string;
|
|
||||||
readonly contract: string;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
readonly kind: "graph";
|
|
||||||
readonly nodes: readonly string[];
|
|
||||||
readonly route: string;
|
|
||||||
readonly inputBinding: string;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
readonly kind: "repair";
|
|
||||||
readonly diagnostic: string;
|
|
||||||
readonly correction: string;
|
|
||||||
readonly status: string;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
readonly kind: "artifact";
|
|
||||||
readonly artifactId: string;
|
|
||||||
readonly version: number;
|
|
||||||
readonly requiredSources: number;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
readonly kind: "bindings";
|
|
||||||
readonly deploymentId: string;
|
|
||||||
readonly bindings: readonly { readonly requirement: string; readonly source: string }[];
|
|
||||||
readonly status: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const visualForPhase = (phase: AuthoringPhaseId): AuthoringPhaseVisualModel => {
|
|
||||||
switch (phase) {
|
|
||||||
case "discover":
|
|
||||||
return {
|
|
||||||
kind: "inventory",
|
|
||||||
sources: ["local.lda_docs", "local.lda_report", "local.issue_board"],
|
|
||||||
capability: "local.lda_report.analyze_documents",
|
|
||||||
contract: "documents → analysis",
|
|
||||||
};
|
|
||||||
case "draft":
|
|
||||||
return {
|
|
||||||
kind: "graph",
|
|
||||||
nodes: ["read_documents", "analyze"],
|
|
||||||
route: "ok → end",
|
|
||||||
inputBinding: "state.documents → documents",
|
|
||||||
};
|
|
||||||
case "validate":
|
|
||||||
{
|
|
||||||
const diagnostic = reviewedAuthoringEvidenceFor("diagnose");
|
|
||||||
const repair = reviewedAuthoringEvidenceFor("repair");
|
|
||||||
if (diagnostic.kind !== "diagnostic" || repair.kind !== "repair") {
|
|
||||||
throw new Error("reviewed validation evidence has an unexpected shape");
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
kind: "repair",
|
|
||||||
diagnostic: `${diagnostic.diagnostic.code} at ${diagnostic.diagnostic.path}: ${diagnostic.diagnostic.message}`,
|
|
||||||
correction: repair.command,
|
|
||||||
status: `Revision ${repair.toRevision}: ${repair.status}`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case "artifact":
|
|
||||||
return {
|
|
||||||
kind: "artifact",
|
|
||||||
artifactId: "lda_report_case_study",
|
|
||||||
version: 1,
|
|
||||||
requiredSources: 3,
|
|
||||||
};
|
|
||||||
case "deployment":
|
|
||||||
return {
|
|
||||||
kind: "bindings",
|
|
||||||
deploymentId: "lda_report_case_study.default",
|
|
||||||
bindings: [
|
|
||||||
{ requirement: "local.lda_docs", source: "local.lda_docs" },
|
|
||||||
{ requirement: "local.lda_report", source: "local.lda_report" },
|
|
||||||
{ requirement: "local.issue_board", source: "local.issue_board" },
|
|
||||||
],
|
|
||||||
status: "Deployment valid",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Projects one phase of the prepared authoring recording for presentation.
|
* Projects one phase of the prepared authoring recording for presentation.
|
||||||
*
|
*
|
||||||
@@ -135,7 +51,6 @@ export const projectPreparedAuthoringPhase = (
|
|||||||
.join(" ") || found.label,
|
.join(" ") || found.label,
|
||||||
proof: found.proof,
|
proof: found.proof,
|
||||||
commands: found.commands,
|
commands: found.commands,
|
||||||
visual: visualForPhase(found.phase),
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -154,7 +69,7 @@ export const projectPreparedLifecycleStep = (
|
|||||||
const evidence = reviewedAuthoringEvidenceFor(step);
|
const evidence = reviewedAuthoringEvidenceFor(step);
|
||||||
// Diagnose and repair are presentation choreography over one factual
|
// Diagnose and repair are presentation choreography over one factual
|
||||||
// recording phase; they select distinct evidence without duplicating it.
|
// recording phase; they select distinct evidence without duplicating it.
|
||||||
const commandIndex = step === "repair" ? 1 : 0;
|
const commandIndex = step === "repair" ? 2 : step === "diagnose" ? 1 : 0;
|
||||||
const primaryCommand = phase.commands[commandIndex];
|
const primaryCommand = phase.commands[commandIndex];
|
||||||
if (primaryCommand === undefined) {
|
if (primaryCommand === undefined) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ describe("projectPreparedAuthoring", () => {
|
|||||||
"workflow.draft_workspaces.create_from_capability",
|
"workflow.draft_workspaces.create_from_capability",
|
||||||
"workflow.draft_workspaces.add_step_from_capability",
|
"workflow.draft_workspaces.add_step_from_capability",
|
||||||
"workflow.draft_workspaces.get",
|
"workflow.draft_workspaces.get",
|
||||||
|
"workflow.draft_workspaces.remove_route",
|
||||||
"workflow.draft_workspaces.validate",
|
"workflow.draft_workspaces.validate",
|
||||||
"workflow.draft_workspaces.set_route",
|
"workflow.draft_workspaces.set_route",
|
||||||
"workflow.draft_workspaces.compile",
|
"workflow.draft_workspaces.compile",
|
||||||
@@ -109,6 +110,7 @@ describe("projectPreparedAuthoring", () => {
|
|||||||
expect(commands.some((command) => command === "wf cap inspect local.lda_report.analyze_documents")).toBe(true);
|
expect(commands.some((command) => command === "wf cap inspect local.lda_report.analyze_documents")).toBe(true);
|
||||||
expect(commands.some((command) => command === "wf schema")).toBe(true);
|
expect(commands.some((command) => command === "wf schema")).toBe(true);
|
||||||
expect(commands.some((command) => command.startsWith("wf draft add-step lda_report_workflow"))).toBe(true);
|
expect(commands.some((command) => command.startsWith("wf draft add-step lda_report_workflow"))).toBe(true);
|
||||||
|
expect(commands.some((command) => command === "wf draft remove-route lda_report_workflow --revision 2 --step analyze --outcome ok")).toBe(true);
|
||||||
expect(commands.some((command) => command === "wf draft validate lda_report_workflow")).toBe(true);
|
expect(commands.some((command) => command === "wf draft validate lda_report_workflow")).toBe(true);
|
||||||
expect(commands.some((command) => command === "wf draft set-route lda_report_workflow --revision 3 --step analyze --outcome ok --to __end__")).toBe(true);
|
expect(commands.some((command) => command === "wf draft set-route lda_report_workflow --revision 3 --step analyze --outcome ok --to __end__")).toBe(true);
|
||||||
expect(commands.some((command) => command === "wf draft compile lda_report_workflow")).toBe(true);
|
expect(commands.some((command) => command === "wf draft compile lda_report_workflow")).toBe(true);
|
||||||
|
|||||||
@@ -160,12 +160,22 @@ const recording: readonly PreparedAuthoringPhase[] = [
|
|||||||
beatId: "validate",
|
beatId: "validate",
|
||||||
label: "Validate",
|
label: "Validate",
|
||||||
commands: [
|
commands: [
|
||||||
|
{
|
||||||
|
title: "workflow.draft_workspaces.remove_route",
|
||||||
|
command:
|
||||||
|
"wf draft remove-route lda_report_workflow --revision 2 --step analyze --outcome ok",
|
||||||
|
summary: "Prepare a validation fault injection by removing the terminal route",
|
||||||
|
result: "success",
|
||||||
|
detail:
|
||||||
|
"Prepared fault injection: intentionally remove analyze.ok from valid revision 2; this produces revision 3 invalid with missing_outcome_edge.",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: "workflow.draft_workspaces.validate",
|
title: "workflow.draft_workspaces.validate",
|
||||||
command: "wf draft validate lda_report_workflow",
|
command: "wf draft validate lda_report_workflow",
|
||||||
summary: "Validate the workflow draft",
|
summary: "Validate the workflow draft",
|
||||||
result: "diagnostic",
|
result: "diagnostic",
|
||||||
detail: "missing_outcome_edge at nodes[analyze]: reachable node is missing edges for outcomes ['ok']",
|
detail:
|
||||||
|
"Revision 3 is invalid: missing_outcome_edge at nodes[analyze]: reachable node is missing edges for outcomes ['ok']",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "workflow.draft_workspaces.set_route",
|
title: "workflow.draft_workspaces.set_route",
|
||||||
@@ -182,7 +192,7 @@ const recording: readonly PreparedAuthoringPhase[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
role: "assistant",
|
role: "assistant",
|
||||||
text: "Running diagnosis now. I'll bind the source and repair any issues found in the draft graph.",
|
text: "Revision 2 is valid. For this prepared validation path, I'll intentionally remove analyze.ok, validate the resulting revision 3, and then repair it.",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
proof: [
|
proof: [
|
||||||
|
|||||||
@@ -34,6 +34,12 @@ describe("reviewed authoring evidence", () => {
|
|||||||
path: "nodes[analyze]",
|
path: "nodes[analyze]",
|
||||||
message: "reachable node is missing edges for outcomes ['ok']",
|
message: "reachable node is missing edges for outcomes ['ok']",
|
||||||
},
|
},
|
||||||
|
faultInjection: {
|
||||||
|
command: "wf draft remove-route lda_report_workflow --revision 2 --step analyze --outcome ok",
|
||||||
|
fromRevision: 2,
|
||||||
|
toRevision: 3,
|
||||||
|
label: "prepared fault injection",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(reviewedAuthoringEvidenceFor("repair")).toMatchObject({
|
expect(reviewedAuthoringEvidenceFor("repair")).toMatchObject({
|
||||||
|
|||||||
@@ -33,6 +33,12 @@ export type ReviewedAuthoringEvidence =
|
|||||||
readonly message: string;
|
readonly message: string;
|
||||||
readonly explanation: string;
|
readonly explanation: string;
|
||||||
};
|
};
|
||||||
|
readonly faultInjection: {
|
||||||
|
readonly command: string;
|
||||||
|
readonly fromRevision: 2;
|
||||||
|
readonly toRevision: 3;
|
||||||
|
readonly label: "prepared fault injection";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
readonly kind: "repair";
|
readonly kind: "repair";
|
||||||
@@ -107,6 +113,13 @@ const reviewedAuthoringEvidence: Readonly<
|
|||||||
message: "reachable node is missing edges for outcomes ['ok']",
|
message: "reachable node is missing edges for outcomes ['ok']",
|
||||||
explanation: "The workflow cannot prove where execution goes next.",
|
explanation: "The workflow cannot prove where execution goes next.",
|
||||||
},
|
},
|
||||||
|
faultInjection: {
|
||||||
|
command:
|
||||||
|
"wf draft remove-route lda_report_workflow --revision 2 --step analyze --outcome ok",
|
||||||
|
fromRevision: 2,
|
||||||
|
toRevision: 3,
|
||||||
|
label: "prepared fault injection",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
repair: {
|
repair: {
|
||||||
kind: "repair",
|
kind: "repair",
|
||||||
|
|||||||
@@ -183,6 +183,17 @@ describe("presentation.css", () => {
|
|||||||
expect(narrowRows).toContain("grid-template-columns: minmax(0, 1fr);");
|
expect(narrowRows).toContain("grid-template-columns: minmax(0, 1fr);");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("bounds narrow lifecycle results to a viewport-relative scrollport", () => {
|
||||||
|
const narrowContainer = cssBlock(css, "@container presentation-canvas (max-width: 600px)") ?? "";
|
||||||
|
const narrowResult = cssBlocks(narrowContainer, '.prepared-lifecycle-scene[data-presentation-surface="editorial"] .authoring-result')
|
||||||
|
.find((body) => body.includes("max-height: min(34rem, 56vh);"));
|
||||||
|
|
||||||
|
expect(narrowResult).toContain("height: min(34rem, 56vh);");
|
||||||
|
expect(narrowResult).toContain("max-height: min(34rem, 56vh);");
|
||||||
|
expect(narrowResult).toContain("overflow: auto;");
|
||||||
|
expect(narrowResult).not.toContain("max-height: 100%;");
|
||||||
|
});
|
||||||
|
|
||||||
it("gives the prepared lifecycle rail and operation frame the primary hierarchy", () => {
|
it("gives the prepared lifecycle rail and operation frame the primary hierarchy", () => {
|
||||||
const frameRules = cssBlocks(css, '.prepared-lifecycle-scene[data-presentation-surface="editorial"] .prepared-lifecycle-scene__frame');
|
const frameRules = cssBlocks(css, '.prepared-lifecycle-scene[data-presentation-surface="editorial"] .prepared-lifecycle-scene__frame');
|
||||||
const editorialFrame = frameRules.find((body) => body.includes("background: var(--authoring-paper);"));
|
const editorialFrame = frameRules.find((body) => body.includes("background: var(--authoring-paper);"));
|
||||||
@@ -263,9 +274,10 @@ describe("presentation.css", () => {
|
|||||||
expect(narrowAssistant).toContain("max-height: min(24rem, 60vh);");
|
expect(narrowAssistant).toContain("max-height: min(24rem, 60vh);");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("does not cap lifecycle evidence on wide presentation canvases", () => {
|
it("does not add a wide-canvas lifecycle evidence cap", () => {
|
||||||
expect(css).not.toContain("@container presentation-canvas (min-width: 1500px)");
|
expect(css).not.toContain("@container presentation-canvas (min-width: 1500px)");
|
||||||
expect(css).not.toContain("max-height: min(34rem, 56vh);");
|
const narrowContainer = cssBlock(css, "@container presentation-canvas (max-width: 600px)") ?? "";
|
||||||
|
expect(narrowContainer).toContain("max-height: min(34rem, 56vh);");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("bounds prepared conversation scrolling and recenters the agent handoff at compact stage widths", () => {
|
it("bounds prepared conversation scrolling and recenters the agent handoff at compact stage widths", () => {
|
||||||
|
|||||||
@@ -4007,8 +4007,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.prepared-lifecycle-scene[data-presentation-surface="editorial"] .authoring-result {
|
.prepared-lifecycle-scene[data-presentation-surface="editorial"] .authoring-result {
|
||||||
height: auto;
|
height: min(34rem, 56vh);
|
||||||
max-height: 100%;
|
max-height: min(34rem, 56vh);
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
padding-inline: 0;
|
padding-inline: 0;
|
||||||
}
|
}
|
||||||
@@ -4229,6 +4229,30 @@
|
|||||||
border-inline-start: 3px solid var(--accent-amber);
|
border-inline-start: 3px solid var(--accent-amber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.authoring-result__fault-injection {
|
||||||
|
display: grid;
|
||||||
|
gap: 0.35rem;
|
||||||
|
min-width: 0;
|
||||||
|
padding: 0.75rem 0.9rem;
|
||||||
|
border: 1px dashed var(--authoring-rule, var(--stage-line));
|
||||||
|
color: var(--authoring-muted, var(--text-secondary));
|
||||||
|
}
|
||||||
|
|
||||||
|
.authoring-result__fault-injection span {
|
||||||
|
font: 700 0.64rem/1.1 var(--font-evidence);
|
||||||
|
letter-spacing: 0.07em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.authoring-result__fault-injection code {
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
|
||||||
|
.authoring-result__fault-injection p {
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
.authoring-result__prior {
|
.authoring-result__prior {
|
||||||
padding-bottom: 0.85rem;
|
padding-bottom: 0.85rem;
|
||||||
border-bottom: 1px solid var(--authoring-rule, var(--stage-line));
|
border-bottom: 1px solid var(--authoring-rule, var(--stage-line));
|
||||||
|
|||||||
Reference in New Issue
Block a user