{"version":3,"file":"cavecrew-runtime.test.d.ts","sourceRoot":"","sources":["../../src/core/cavecrew-runtime.test.ts"],"names":[],"mappings":"","sourcesContent":["import { mkdtemp, readFile, rm } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { describe, expect, it } from \"vitest\";\nimport { runCavecrew } from \"./cavecrew-runtime.js\";\n\nconst investigation = (assignment: string) => ({\n\tobjective: assignment,\n\tsummary: \"fixture\",\n\tflow: [\"discover\"],\n\trootCauses: [],\n\trelevantFiles: [\"one.txt\"],\n\tunknowns: [],\n\trecommendedNextAgent: \"planner\",\n});\n\nconst plan = {\n\tscope: [\"one.txt\", \"two.txt\"],\n\tnonGoals: [],\n\timplementationSteps: [\"write fixture files\"],\n\tinvariants: [\"bounded\"],\n\tfocusedTests: [\"fixture\"],\n\tacceptanceCriteria: [\"files exist\"],\n\trollbackExpectations: [\"restore checkpoint\"],\n};\n\nconst builder = {\n\tobjective: \"fixture\",\n\tstatus: \"implemented\" as const,\n\tfilesChanged: [\"one.txt\", \"two.txt\"],\n\tvalidations: [\"fixture-pass\"],\n\trollbackState: \"confirmed\" as const,\n\tremainingRisks: [],\n};\n\nconst review = { verdict: \"pass\" as const, findings: [], missingTests: [], acceptanceGaps: [] };\n\nasync function fixture(overrides: Partial<Parameters<typeof runCavecrew>[0][\"fixtures\"]> = {}) {\n\tconst cwd = await mkdtemp(join(tmpdir(), \"jensen-cavecrew-\"));\n\tconst storageDir = join(cwd, \".state\");\n\tconst fixtures = {\n\t\tinvestigator: async (assignment: string) => investigation(assignment),\n\t\tplanner: async () => plan,\n\t\tbuilder: async () => ({\n\t\t\tedits: [\n\t\t\t\t{ kind: \"create_file\" as const, path: \"one.txt\", content: \"one\" },\n\t\t\t\t{ kind: \"create_file\" as const, path: \"two.txt\", content: \"two\" },\n\t\t\t],\n\t\t\toutput: builder,\n\t\t}),\n\t\treviewer: async () => review,\n\t\t...overrides,\n\t};\n\treturn { cwd, storageDir, fixtures };\n}\n\ndescribe(\"deterministic Cavecrew runtime\", () => {\n\tit(\"runs parallel investigators, planner, transactional builder, and reviewer\", async () => {\n\t\tconst context = await fixture();\n\t\ttry {\n\t\t\tconst result = await runCavecrew({ objective: \"fixture\", assignments: [\"a\", \"b\"], ...context });\n\t\t\texpect(result.state).toBe(\"completed\");\n\t\t\texpect(result.investigations.map((item) => item.objective)).toEqual([\"a\", \"b\"]);\n\t\t\texpect(result.builder?.rollbackState).toBe(\"confirmed\");\n\t\t\texpect(await readFile(join(context.cwd, \"one.txt\"), \"utf8\")).toBe(\"one\");\n\t\t} finally {\n\t\t\tawait rm(context.cwd, { recursive: true, force: true });\n\t\t}\n\t});\n\n\tit(\"rejects a plan beyond the builder scope before mutation\", async () => {\n\t\tconst context = await fixture({ planner: async () => ({ ...plan, scope: [\"a\", \"b\", \"c\"] }) });\n\t\ttry {\n\t\t\tconst result = await runCavecrew({ objective: \"fixture\", assignments: [\"a\"], ...context });\n\t\t\texpect(result.state).toBe(\"plan_invalid\");\n\t\t\texpect(await readFile(join(context.cwd, \"one.txt\"), \"utf8\").catch(() => null)).toBeNull();\n\t\t} finally {\n\t\t\tawait rm(context.cwd, { recursive: true, force: true });\n\t\t}\n\t});\n\n\tit(\"cancels before starting the mutation barrier\", async () => {\n\t\tconst controller = new AbortController();\n\t\tcontroller.abort();\n\t\tconst context = await fixture();\n\t\ttry {\n\t\t\tconst result = await runCavecrew({\n\t\t\t\tobjective: \"fixture\",\n\t\t\t\tassignments: [\"a\"],\n\t\t\t\tsignal: controller.signal,\n\t\t\t\t...context,\n\t\t\t});\n\t\t\texpect(result.state).toBe(\"cancelled\");\n\t\t} finally {\n\t\t\tawait rm(context.cwd, { recursive: true, force: true });\n\t\t}\n\t});\n});\n"]}