/* RFC-1297: leitstand.state.reconcile handler — writes lastPropagated with state "reconciled" and a live-state-reconciled Bordbuch event when live ≠ recorded; exits 1 when the live identity is unreachable. Not a contract source of truth — the module under test owns the authoritative behavior; fixtures are minimal scaffolding only. RFC-1297: initial — handler test. RFC-1297 */ import { test, expect, vi, beforeEach, afterEach } from "vitest"; import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { createDefaultIO } from "@warpgogol/werkstatt-shared/kernel/workspace-io"; import type { KernelRuntimeContext } from "@warpgogol/werkstatt-engine/kernel"; import { runLeitstandStateReconcile } from "./state-reconcile.ts"; import { readSystemState } from "../sternsystem/registry-io.ts"; import { readBordbuch } from "../bordbuch/bordbuch-io.ts"; const mockFetch = vi.fn(); vi.mock("./wba-signer.ts", () => ({ resolveOutboundAgentClient: vi.fn(async () => ({ client: { fetch: (...args: unknown[]) => mockFetch(...args) }, })), })); const systemId = "acme"; let tmpDir: string; let werkstattRoot: string; let context: KernelRuntimeContext; function jsonResponse(status: number, body: unknown): Response { return new Response(JSON.stringify(body), { status, headers: { "content-type": "application/json" }, }); } beforeEach(() => { mockFetch.mockReset(); tmpDir = mkdtempSync(join(tmpdir(), "state-reconcile-")); werkstattRoot = join(tmpDir, "werkstatt"); const cacheDir = join(tmpDir, "systems-cache", systemId); mkdirSync(werkstattRoot, { recursive: true }); mkdirSync(cacheDir, { recursive: true }); writeFileSync( join(cacheDir, "system-config.yaml"), [ "schemaVersion: 1.0.0", `id: ${systemId}`, "cosmicStar: Vega", "mirrors:", " - path: ../systems-cache/acme", " storageType: non-bare", "pinnedPlatform: 6.346.1", "status: active", "registeredAt: 2026-01-01T00:00:00.000Z", "deployment:", " adapter: cloudflare-workers", " channels:", " dev:", " workerName: dev-acme", " url: https://dev.example.com", " alt:", " workerName: alt-acme", " url: https://alt.example.com", " main:", " workerName: acme", " url: https://example.com", "", ].join("\n"), ); writeFileSync( join(cacheDir, "system-state.yaml"), [ "schemaVersion: 1.0.0", `systemId: ${systemId}`, "currentMission: null", "lastRelease: acme-r000036", "lastPropagated:", " main:", " releaseId: acme-r000036", " at: 2026-10-14T19:53:51.751Z", " healthy: true", " state: succeeded", " operationId: op-test-0001", " leaseExpiresAt: null", "", ].join("\n"), ); context = { workspaceRoot: werkstattRoot, io: createDefaultIO().io, logger: { info: () => {}, success: () => {}, warn: () => {}, error: () => {}, debug: () => {} }, } as unknown as KernelRuntimeContext; }); afterEach(() => { rmSync(tmpDir, { recursive: true, force: true }); }); const flags = { site: systemId, channel: "main", "from-live": true, reason: "operator verified the out-of-band rollback", }; test("reconciles a drifted channel: state written, Bordbuch event appended", async () => { mockFetch.mockResolvedValue(jsonResponse(200, { releaseId: "acme-r000035" })); const result = await runLeitstandStateReconcile({ flags, argv: [] }, context); expect(result.exitCode).toBe(0); const state = await readSystemState(werkstattRoot, systemId); const main = state.lastPropagated.main; expect(main?.releaseId).toBe("acme-r000035"); expect(main?.state).toBe("reconciled"); expect(main?.healthy).toBeNull(); const entries = await readBordbuch(werkstattRoot, systemId); const reconciled = entries.filter((e) => e.kind === "live-state-reconciled"); expect(reconciled).toHaveLength(1); expect(reconciled[0].summary).toContain("acme-r000036"); expect(reconciled[0].summary).toContain("acme-r000035"); }); test("exits 1 when the live identity is unreachable — nothing truthful to record", async () => { mockFetch.mockRejectedValue(new Error("connect ECONNREFUSED")); const result = await runLeitstandStateReconcile({ flags, argv: [] }, context); expect(result.exitCode).toBe(1); const state = await readSystemState(werkstattRoot, systemId); expect(state.lastPropagated.main?.releaseId).toBe("acme-r000036"); const entries = await readBordbuch(werkstattRoot, systemId); expect(entries.filter((e) => e.kind === "live-state-reconciled")).toHaveLength(0); }); test("already-consistent live state exits 0 without writing", async () => { mockFetch.mockResolvedValue(jsonResponse(200, { releaseId: "acme-r000036" })); const result = await runLeitstandStateReconcile({ flags, argv: [] }, context); expect(result.exitCode).toBe(0); expect(result.data?.outcome).toBe("already-consistent"); const entries = await readBordbuch(werkstattRoot, systemId); expect(entries.filter((e) => e.kind === "live-state-reconciled")).toHaveLength(0); });