42 lines
2.7 KiB
TypeScript
42 lines
2.7 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { reconcileAutonomyPlan } from "../src/services/autonomyReplanner.js";
|
|
import { normalizeAutonomyState } from "../src/repositories/autonomyRepository.js";
|
|
|
|
const state = () => normalizeAutonomyState({ enabled: true, roadmap: { id: "roadmap-1", title: "Release", status: "active", currentPhaseIndex: 0, importedAt: "2026-09-12T10:00:00.000Z", phases: [{ id: "phase-1", title: "Build", objective: "Ship", status: "executing", items: [{ id: "item-1", title: "Feature", source: "delivery", deliveryId: "delivery-1", status: "in_progress", attempts: 1 }] }] } });
|
|
|
|
describe("autonomy reality reconciliation", () => {
|
|
it("preserves work completed by an external merge", () => {
|
|
const result = reconcileAutonomyPlan(state(), [{ itemId: "item-1", deliveryId: "delivery-1", status: "pull_request_open", mergeCommitSha: "abc123", validationEvidence: "head123" }]);
|
|
const item = result.state.roadmap?.phases[0]?.items[0];
|
|
expect(item?.status).toBe("completed");
|
|
expect(item?.completionEvidence).toEqual(expect.arrayContaining(["delivery:delivery-1", "merge:abc123", "head123"]));
|
|
});
|
|
|
|
it("adds bounded recovery work for superseded delivery state", () => {
|
|
const result = reconcileAutonomyPlan(state(), [{ itemId: "item-1", deliveryId: "delivery-1", status: "superseded", supersededBy: "delivery-2" }]);
|
|
expect(result.repairItems).toHaveLength(1);
|
|
expect(result.state.roadmap?.phases[0]?.items).toHaveLength(2);
|
|
expect(result.state.roadmap?.phases[0]?.items[1]?.source).toBe("recovery");
|
|
});
|
|
|
|
it("replans a previously completed item when its delivery is superseded", () => {
|
|
const completed = state();
|
|
completed.roadmap!.phases[0].items[0].status = "completed";
|
|
const result = reconcileAutonomyPlan(completed, [{ itemId: "item-1", deliveryId: "delivery-1", status: "merged", supersededBy: "delivery-2" }]);
|
|
expect(result.repairItems).toHaveLength(1);
|
|
expect(result.state.roadmap?.phases[0]?.items[0]).toMatchObject({ status: "completed", supersededBy: "delivery-2" });
|
|
});
|
|
|
|
it("clears an external wait when the observed delivery becomes available again", () => {
|
|
const waiting = state();
|
|
const item = waiting.roadmap?.phases[0]?.items[0];
|
|
if (!item) throw new Error("test item missing");
|
|
item.waitingExternal = true;
|
|
item.lastError = "Provider unavailable";
|
|
const result = reconcileAutonomyPlan(waiting, [{ itemId: item.id, deliveryId: "delivery-1", status: "executing" }]);
|
|
expect(result.changed).toBe(true);
|
|
expect(result.state.roadmap?.phases[0]?.items[0]).toMatchObject({ waitingExternal: false, status: "in_progress" });
|
|
expect(result.state.roadmap?.phases[0]?.items[0]?.lastError).toBeUndefined();
|
|
});
|
|
});
|