import { describe, expect, it } from "vitest"; import { emptyArtifact, serializeArtifact, type Artifact, type Proposal, } from "../src/model"; const agent = { kind: "agent" as const, id: "claude", agent: { sdk: "@cline/sdk", model: "sonnet", sessionId: "s1" }, }; describe("Proposal model (spec ยง6.3, INV-13)", () => { it("serializes proposals with stable field order and survives a round-trip", () => { const a = emptyArtifact("docs/x.md"); a.anchors["a_1"] = { fingerprint: { text: "old text", before: "", after: "", lineHint: 0 }, }; const p: Proposal = { id: "pr_1", anchorId: "a_1", replacement: "new text", author: agent, createdAt: "2026-06-10T00:00:00.000Z", turnId: "turn-1", instruction: "tighten", }; a.proposals.push(p); const reloaded = JSON.parse(serializeArtifact(a)) as Artifact; expect(reloaded.proposals).toHaveLength(1); expect(reloaded.proposals[0]).toEqual(p); // optional fields are OMITTED (not null) when absent const bare: Proposal = { id: "pr_2", anchorId: "a_1", replacement: "r", author: agent, createdAt: "2026-06-10T00:00:00.000Z", }; a.proposals.push(bare); const again = JSON.parse(serializeArtifact(a)) as Artifact; expect("turnId" in again.proposals[1]).toBe(false); expect("instruction" in again.proposals[1]).toBe(false); // serialization is byte-stable (INV-2) expect(serializeArtifact(again)).toBe(serializeArtifact(a)); }); });