import { Either, Schema } from "effect"; import { describe, expect, it } from "vitest"; import type { WorkflowOperationParams, WorkflowOperationResult, } from "../generated/workflow-contract.js"; import { workflowRuntimeContract } from "../generated/workflow-contract.js"; import { runtimeSchemasFor } from "./runtime-schema.js"; const accepts = (schema: Schema.Schema.AnyNoContext, value: unknown): boolean => Either.isRight( Schema.decodeUnknownEither(schema)(value, { onExcessProperty: "error" }), ); describe("runtimeSchemasFor", () => { it("contains exactly the authored RPC cohort", () => { expect(Object.keys(workflowRuntimeContract.operations)).toEqual([ "workflow.artifacts.inspect", "workflow.artifacts.list", "workflow.capabilities.call", "workflow.capabilities.inspect", "workflow.capabilities.list", "workflow.deployments.inspect", "workflow.deployments.list", "workflow.deployments.validate", "workflow.draft_workspaces.add_step_from_capability", "workflow.draft_workspaces.create_empty", "workflow.draft_workspaces.create_from_capability", "workflow.draft_workspaces.get", "workflow.draft_workspaces.list", "workflow.draft_workspaces.set_route", "workflow.draft_workspaces.set_step_input_bindings", "workflow.draft_workspaces.set_step_output_bindings", "workflow.draft_workspaces.update_capability_step", "workflow.draft_workspaces.validate", "workflow.health", "workflow.runs.inspect", "workflow.runs.list", "workflow.runs.resume", "workflow.runs.start", "workflow.runs.trace", "workflow.sources.list", ]); }); it("exposes the six draft authoring runtime schemas without generic replacement", () => { expect( runtimeSchemasFor("workflow.draft_workspaces.create_empty"), ).toBeDefined(); expect( runtimeSchemasFor("workflow.draft_workspaces.create_from_capability"), ).toBeDefined(); expect( runtimeSchemasFor("workflow.draft_workspaces.add_step_from_capability"), ).toBeDefined(); expect( runtimeSchemasFor("workflow.draft_workspaces.update_capability_step"), ).toBeDefined(); expect(runtimeSchemasFor("workflow.draft_workspaces.set_route")).toBeDefined(); expect(runtimeSchemasFor("workflow.draft_workspaces.validate")).toBeDefined(); expect( Object.hasOwn(workflowRuntimeContract.operations, "workflow.draft_workspaces.replace_document"), ).toBe(false); }); it("accepts every JSON literal category in focused input bindings", () => { const schemas = runtimeSchemasFor( "workflow.draft_workspaces.set_step_input_bindings", ); const values = [ "markdown", 3.14, true, null, ["markdown", false], { format: "markdown", options: { strict: true } }, ]; for (const value of values) { expect( accepts(schemas.payload, { workspace_id: "console.demo", revision: 3, step_id: "render", bindings: [{ target: "literal", value }], }), ).toBe(true); } }); it("rejects an input expression over the canonical 1024-node budget", () => { const schemas = runtimeSchemasFor( "workflow.draft_workspaces.set_step_input_bindings", ); const expression = { kind: "array", items: Array.from({ length: 1025 }, () => ({ kind: "literal", value: "child", })), }; expect( accepts(schemas.payload, { workspace_id: "console.demo", revision: 3, step_id: "render", bindings: [{ target: "request", expression }], }), ).toBe(false); }); it("accepts a large ordinary JSON value shaped like a literal in a simple binding", () => { const schemas = runtimeSchemasFor( "workflow.draft_workspaces.set_step_input_bindings", ); const ordinaryValue = { kind: "literal", value: Array.from({ length: 1025 }, () => ({})), }; expect( accepts(schemas.payload, { workspace_id: "console.demo", revision: 3, step_id: "render", bindings: [{ target: "request", value: ordinaryValue }], }), ).toBe(true); }); it("accepts a large ordinary JSON value shaped like a literal as workflow input", () => { const schemas = runtimeSchemasFor("workflow.runs.start"); const ordinaryValue = { kind: "literal", value: Array.from({ length: 1025 }, () => ({})), }; expect( accepts(schemas.payload, { deployment_id: "report.default", workflow_input: { request: ordinaryValue }, }), ).toBe(true); }); it("counts nested literal array and object containers in the input budget", () => { const schemas = runtimeSchemasFor( "workflow.draft_workspaces.set_step_input_bindings", ); const expression = { kind: "literal", value: Array.from({ length: 1023 }, () => ({})), }; expect( accepts(schemas.payload, { workspace_id: "console.demo", revision: 3, step_id: "render", bindings: [{ target: "request", expression }], }), ).toBe(false); }); it("returns typed payload and result schemas for a generated operation", () => { const schemas = runtimeSchemasFor("workflow.health"); const payload: WorkflowOperationParams<"workflow.health"> = Schema.decodeUnknownSync(schemas.payload)({}); const result: WorkflowOperationResult<"workflow.health"> = Schema.decodeUnknownSync(schemas.success)({ status: "ok", store_root: "C:/store", }); expect(payload).toEqual({}); expect(result.status).toBe("ok"); expect(accepts(schemas.success, { status: "bad", store_root: "C:/store" })).toBe( false, ); }); it("keeps generated payload constraints at runtime", () => { const schemas = runtimeSchemasFor("workflow.sources.list"); expect(accepts(schemas.payload, { limit: 100 })).toBe(true); expect(accepts(schemas.payload, { limit: 101 })).toBe(false); expect(accepts(schemas.payload, { extra: true })).toBe(false); }); it("rejects adversarial nesting before recursive JSON decoding", () => { const schemas = runtimeSchemasFor("workflow.artifacts.inspect"); let plan: unknown = "leaf"; for (let depth = 0; depth < 70; depth += 1) plan = { nested: plan }; expect( accepts(schemas.success, { id: "report", version: 1, title: "Report", kind: "workflow", description: null, outcomes: [], input_schema: {}, output_schema: {}, plan, required_capabilities: [], workflow_dependencies: {}, created_from_catalog_version: null, }), ).toBe(false); }); it("accepts shared acyclic runtime values", () => { const schemas = runtimeSchemasFor("workflow.artifacts.inspect"); const sharedSchema = {}; const result = { id: "report", version: 1, title: "Report", kind: "workflow", description: null, outcomes: [], input_schema: sharedSchema, output_schema: sharedSchema, plan: {}, required_capabilities: [], workflow_dependencies: {}, created_from_catalog_version: null, }; expect(accepts(schemas.success, result)).toBe(true); }); it("rejects cyclic runtime values", () => { const schemas = runtimeSchemasFor("workflow.artifacts.inspect"); const cyclic: Record = {}; cyclic.self = cyclic; const result = { id: "report", version: 1, title: "Report", kind: "workflow", description: null, outcomes: [], input_schema: {}, output_schema: {}, plan: cyclic, required_capabilities: [], workflow_dependencies: {}, created_from_catalog_version: null, }; expect(accepts(schemas.success, result)).toBe(false); }); it("accepts the maximum permitted container depth", () => { const schemas = runtimeSchemasFor("workflow.artifacts.inspect"); let plan: unknown = "leaf"; for (let depth = 0; depth < 63; depth += 1) plan = { nested: plan }; expect( accepts(schemas.success, { id: "report", version: 1, title: "Report", kind: "workflow", description: null, outcomes: [], input_schema: {}, output_schema: {}, plan, required_capabilities: [], workflow_dependencies: {}, created_from_catalog_version: null, }), ).toBe(true); }); it("requires the canonical persisted interrupt contract", () => { const schemas = runtimeSchemasFor("workflow.runs.inspect"); const baseRun = { run_id: "run_1", deployment_id: "report.default", artifact_id: "report", artifact_version: 1, status: "interrupted", resume_readiness: "ready", outcome: null, error: null, output: null, diagnostics: [], trace_count: 1, next_actions: { can_continue: true, can_save_now: null, recommended_next_tool: "wf.workflow.resume_run", reason: "run is interrupted", patch_examples: [], warnings: [], }, }; const completeInterrupt = { id: "interrupt_1", frame_id: "frame_1", node_id: "review_issues", kind: "issue_review", payload: {}, resumable: true, route: null, outcomes: ["submitted", "cancelled"], request_schema: { type: "object" }, resume_schema: { type: "object" }, typed: true, }; expect(accepts(schemas.success, { ...baseRun, interrupt: completeInterrupt })).toBe( true, ); expect( accepts(schemas.success, { ...baseRun, interrupt: { kind: "issue_review", payload: {}, outcomes: [] }, }), ).toBe(false); expect( accepts(schemas.success, { ...baseRun, run_id: null, status: "failed", resume_readiness: null, interrupt: null, }), ).toBe(true); }); it("keeps canonical run input defaults optional", () => { const start = runtimeSchemasFor("workflow.runs.start"); const resume = runtimeSchemasFor("workflow.runs.resume"); const trace = runtimeSchemasFor("workflow.runs.trace"); expect(accepts(start.payload, { deployment_id: "report.default" })).toBe(true); expect(accepts(resume.payload, { run_id: "run_1" })).toBe(true); expect(accepts(trace.payload, { run_id: "run_1", trace_range: {} })).toBe(true); expect( accepts(trace.payload, { run_id: "run_1", trace_range: { start: 0, limit: 101 }, }), ).toBe(false); }); it("requires the full run envelope and canonical trace frame identifiers", () => { const schemas = runtimeSchemasFor("workflow.runs.trace"); const trace = [ { frame_id: "frame_1", node_id: "review_issues", step_type: "interrupt", resolved_input: {}, outcome: "submitted", next_node_id: "create_issues", output: {}, state_changes: {}, }, ]; const result = { run_id: "run_1", deployment_id: "report.default", artifact_id: "report", artifact_version: 1, status: "completed", resume_readiness: "not_applicable", interrupt: null, outcome: "completed", error: null, output: {}, diagnostics: [], trace_count: 1, next_actions: { can_continue: false, can_save_now: null, recommended_next_tool: null, reason: "run completed", patch_examples: [], warnings: [], }, trace, trace_start: 0, trace_limit: 50, trace_truncated: false, }; expect(accepts(schemas.success, result)).toBe(true); expect( accepts(schemas.success, { run_id: "run_1", status: "completed", trace, trace_start: 0, trace_limit: 50, trace_truncated: false, }), ).toBe(false); }); });