/* RFC-1325 tests for the provisional workers.dev birth path in sternsystem.register: channel derivation + account cache (AC-2), worker-name collision refusal (AC-3), and pre-write fail-fast ordering. Intake seeding semantics — sternsystem-register-intake.test.ts owns those; this suite only varies the --domain host class. RFC-1325: initial — derivation/collision/env/mismatch coverage with a stubbed Cloudflare adapter. RFC-1325: provisional workers.dev as first-class site host Single host predicate module in werkstatt-shared; provisional registration derives dev/alt/main workers.dev channels from the account subdomain; first dev deploy auto-protects provisional hosts; provisional main responses carry noindex; dns-aid skips provisional sites; site.domain.adopt cuts over to a custom domain. RFC-1325: review r1 — pin-carrying probes, AC-3 write ordering, dns-aid validate parity, hardened host lint RFC-1326: single Cloudflare permission registry, token preflight, birth provisioning */ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { cp, mkdir, mkdtemp, rm, writeFile } from "node:fs/promises"; import { existsSync, readFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { dirname, join } from "node:path"; import { fileURLToPath } from "node:url"; import YAML from "yaml"; import type { KernelCommandInput, KernelRuntimeContext } from "@warpgogol/werkstatt-engine/kernel"; import { createDefaultIO } from "@warpgogol/werkstatt-shared/kernel/workspace-io"; import { getWorkersSubdomain, listWorkerNames } from "../leitstand/adapters/cloudflare-api.ts"; import { registerDeps, runSternsystemRegister } from "./sternsystem-register.ts"; vi.mock("../leitstand/adapters/cloudflare-api.ts", async (importOriginal) => ({ ...(await importOriginal()), getWorkersSubdomain: vi.fn(async () => "syrokomskyi"), listWorkerNames: vi.fn(async () => [] as string[]), })); const FIXTURE = join( dirname(fileURLToPath(import.meta.url)), "..", "intake", "fixtures", "valid-minimal", ); let workspaceRoot: string; function input(flags: Record): KernelCommandInput { return { flags: flags as KernelCommandInput["flags"], argv: [] }; } function context(root: string): KernelRuntimeContext { return { io: createDefaultIO().io, workspaceRoot: root, logger: { section() {}, info() {}, warn() {}, error() {}, success() {} }, dryRun: false, } as unknown as KernelRuntimeContext; } const baseFlags = () => ({ id: "dp7", cosmicStar: "Achernar", mirrors: "../systems-cache/dp7:non-bare", intake: "onboarding/dp7/.input/intake", domain: "dp7.syrokomskyi.workers.dev", biome: "dp7-03", }); const cacheDir = () => join(workspaceRoot, "..", "systems-cache", "dp7"); const cacheFile = () => join(workspaceRoot, "werkstatt.cloudflare.json"); beforeEach(async () => { vi.clearAllMocks(); const testRoot = await mkdtemp(join(tmpdir(), "register-prov-")); workspaceRoot = join(testRoot, "workspace"); await mkdir(join(workspaceRoot, "onboarding", "dp7", ".input"), { recursive: true }); await cp(FIXTURE, join(workspaceRoot, "onboarding", "dp7", ".input", "intake"), { recursive: true, }); await writeFile(join(workspaceRoot, "package.json"), JSON.stringify({ version: "6.0.0" })); await writeFile(join(workspaceRoot, "werkstatt.identity.json"), "{}"); process.env.SIGNING_PRIVATE_KEY = "deadbeef".repeat(8); process.env.CLOUDFLARE_ACCOUNT_ID = "a".repeat(32); process.env.CLOUDFLARE_API_TOKEN = "t".repeat(40); vi.spyOn(registerDeps, "checkBiome").mockResolvedValue(null); vi.mocked(getWorkersSubdomain).mockResolvedValue("syrokomskyi"); vi.mocked(listWorkerNames).mockResolvedValue([]); vi.spyOn(registerDeps, "openMission").mockResolvedValue({ data: { missionId: "dp7-m000001" }, exitCode: 0, } as unknown as Awaited>); vi.spyOn(registerDeps, "provisionExternal").mockResolvedValue({ ok: true, provisioned: ["cloudflare.token.check", "agent.search.index.create"], }); }); afterEach(async () => { vi.restoreAllMocks(); delete process.env.SIGNING_PRIVATE_KEY; delete process.env.CLOUDFLARE_ACCOUNT_ID; delete process.env.CLOUDFLARE_API_TOKEN; await rm(join(workspaceRoot, ".."), { recursive: true, force: true }); }); describe("sternsystem.register provisional host (RFC-1325)", () => { it("AC-2: derives deployment.channels and caches the account subdomain", async () => { const result = await runSternsystemRegister(input(baseFlags()), context(workspaceRoot)); expect(result.data?.status).toBe("pass"); const config = YAML.parse(readFileSync(join(cacheDir(), "system-config.yaml"), "utf8")); expect(config.deployment.adapter).toBe("cloudflare-workers"); expect(config.deployment.channels).toEqual({ dev: { workerName: "dev-dp7", url: "https://dev-dp7.syrokomskyi.workers.dev" }, alt: { workerName: "alt-dp7", url: "https://alt-dp7.syrokomskyi.workers.dev" }, main: { workerName: "dp7", url: "https://dp7.syrokomskyi.workers.dev" }, }); const cache = JSON.parse(readFileSync(cacheFile(), "utf8")); expect(cache).toEqual({ accountId: "a".repeat(32), workersSubdomain: "syrokomskyi" }); expect(getWorkersSubdomain).toHaveBeenCalledOnce(); expect(listWorkerNames).toHaveBeenCalledOnce(); }); it("AC-3: refuses on a worker-name collision before any write", async () => { vi.mocked(listWorkerNames).mockResolvedValue(["dev-dp7", "other"]); await expect( runSternsystemRegister(input(baseFlags()), context(workspaceRoot)), ).rejects.toThrow(/worker-name collision.*dev-dp7/); expect(existsSync(join(cacheDir(), "system-config.yaml"))).toBe(false); expect(existsSync(cacheFile()), "the account cache must not be written on refusal").toBe(false); }); it("fails fast naming the missing env before any write", async () => { delete process.env.CLOUDFLARE_API_TOKEN; await expect( runSternsystemRegister(input(baseFlags()), context(workspaceRoot)), ).rejects.toThrow(/CLOUDFLARE_API_TOKEN/); expect(existsSync(join(cacheDir(), "system-config.yaml"))).toBe(false); }); it("refuses a domain whose worker label differs from --id", async () => { await expect( runSternsystemRegister( input({ ...baseFlags(), domain: "other.syrokomskyi.workers.dev" }), context(workspaceRoot), ), ).rejects.toThrow(/worker 'other'.*--id is 'dp7'/); expect(existsSync(join(cacheDir(), "system-config.yaml"))).toBe(false); }); it("refuses a domain on a different account subdomain", async () => { await expect( runSternsystemRegister( input({ ...baseFlags(), domain: "dp7.foreign.workers.dev" }), context(workspaceRoot), ), ).rejects.toThrow(/account subdomain 'foreign'.*resolves to 'syrokomskyi'/); expect(existsSync(join(cacheDir(), "system-config.yaml"))).toBe(false); expect(existsSync(cacheFile()), "the account cache must not be written on refusal").toBe(false); }); it("reuses the cached account subdomain without re-probing the API", async () => { await writeFile( cacheFile(), JSON.stringify({ accountId: "a".repeat(32), workersSubdomain: "syrokomskyi" }), ); const result = await runSternsystemRegister(input(baseFlags()), context(workspaceRoot)); expect(result.data?.status).toBe("pass"); expect(getWorkersSubdomain).not.toHaveBeenCalled(); expect(listWorkerNames).toHaveBeenCalledOnce(); }); });