/* Unit tests for sternsystem.register — RFC-1125 identity + signing-key preflight (AC-3): register blocks before any file ops when werkstatt.identity.json or the signing key is missing. Not a contract source of truth — the module under test owns the authoritative behavior; fixtures are minimal scaffolding only. RFC-1125: preflight tests — missing identity, missing key, and combined-missing cases all throw with an identity.bootstrap fixHint. */ import "./load-verification.test.ts"; import { test, expect, beforeEach, afterEach } from "vitest"; import { mkdtemp, writeFile, rm } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { runSternsystemRegister } from "../sternsystem-register.ts"; import { IDENTITY_CONFIG_FILENAME } from "../../identity/identity-io.ts"; import type { KernelCommandInput, KernelRuntimeContext } from "@warpgogol/werkstatt-engine/kernel"; import { createDefaultIO } from "@warpgogol/werkstatt-shared/kernel/workspace-io"; let tempDir: string; const savedEnv: Record = {}; beforeEach(async () => { tempDir = await mkdtemp(join(tmpdir(), "sternsystem-register-")); for (const key of ["SIGNING_PRIVATE_KEY", "SIGNING_PRIVATE_KEY_PATH"]) { savedEnv[key] = process.env[key]; delete process.env[key]; } }); afterEach(async () => { for (const key of ["SIGNING_PRIVATE_KEY", "SIGNING_PRIVATE_KEY_PATH"]) { if (savedEnv[key] === undefined) delete process.env[key]; else process.env[key] = savedEnv[key]; } await rm(tempDir, { recursive: true, force: true }); }); function makeInput(): KernelCommandInput { return { args: [], flags: { id: "acme" } } as unknown as KernelCommandInput; } function makeContext(): KernelRuntimeContext { return { io: createDefaultIO().io, workspaceRoot: tempDir, logger: { info: () => {}, warn: () => {}, error: () => {}, success: () => {} }, } as unknown as KernelRuntimeContext; } test("blocks when werkstatt.identity.json and signing key are both missing", async () => { await expect(runSternsystemRegister(makeInput(), makeContext())).rejects.toThrow( /identity\.bootstrap/, ); }); test("blocks when signing key is missing even with identity.json present", async () => { await writeFile(join(tempDir, IDENTITY_CONFIG_FILENAME), "{}"); await expect(runSternsystemRegister(makeInput(), makeContext())).rejects.toThrow( /SIGNING_PRIVATE_KEY/, ); }); test("blocks when identity.json is missing even with signing key set", async () => { process.env.SIGNING_PRIVATE_KEY = "deadbeef".repeat(8); await expect(runSternsystemRegister(makeInput(), makeContext())).rejects.toThrow( /werkstatt\.identity\.json/, ); }); test("preflight fires before any file ops — no systems-cache or missions created", async () => { await expect(runSternsystemRegister(makeInput(), makeContext())).rejects.toThrow(); // The preflight throws before discoverSystems/mission.open — nothing materialized const { readdir } = await import("node:fs/promises"); const entries = await readdir(tempDir); expect(entries.filter((e) => e !== IDENTITY_CONFIG_FILENAME)).toHaveLength(0); });