import { spawnSync } from "node:child_process"; import { mkdtemp, readFile, rm } from "node:fs/promises"; import { tmpdir } from "node:os"; import path from "node:path"; import { describe, expect, it } from "vitest"; type RegistryDefinition = Readonly<{ registryId: string; owner: string; requiredFields: string[]; fieldTypes: Record; path: string; exportName: string; rowsPath?: string; rowKeyFields?: string[]; uniqueFields?: string[]; uniqueFieldSets?: string[][]; consumers?: Array<{ path: string; token: string }>; breakingFields?: string[]; }>; describe("registry governance manifest", () => { it("declares eleven typed, single-owner executable registries", async () => { const governance = JSON.parse( await readFile("config/contracts/registry-governance.json", "utf8"), ); const registries = governance.registries as RegistryDefinition[]; expect(governance.registries).toHaveLength(11); expect(new Set(registries.map((entry) => entry.registryId)).size).toBe( 11, ); expect(registries.every((entry) => entry.owner)).toBe(true); expect( registries.every( (entry) => Array.isArray(entry.requiredFields) && entry.requiredFields.length > 0 && entry.fieldTypes && Object.keys(entry.fieldTypes).length > 0, ), ).toBe(true); }); it("governs the installed invalidation graph and wire versions at their real exports", async () => { const governance = JSON.parse( await readFile("config/contracts/registry-governance.json", "utf8"), ) as { registries: RegistryDefinition[] }; const byId = new Map( governance.registries.map((registry) => [registry.registryId, registry]), ); expect(byId.get("FE-REG-QUERY-INVALIDATION")).toMatchObject({ path: "src/features/installed-feature-contracts.ts", exportName: "INVALIDATION_REGISTRY", rowsPath: "edges", rowKeyFields: [ "topicId", "namespace.namespaceId", "namespace.namespaceVersion", ], uniqueFieldSets: [ [ "topicId", "namespace.namespaceId", "namespace.namespaceVersion", ], ], consumers: [ { path: "src/bootstrap/runtime-adapters.ts", token: "indexInvalidationRegistry(INVALIDATION_REGISTRY)", }, ], breakingFields: [ "topicId", "namespace.namespaceId", "namespace.namespaceVersion", ], }); expect(byId.get("FE-REG-QUERY-INVALIDATION-TOPIC-VERSION")).toMatchObject({ path: "src/features/installed-feature-contracts.ts", exportName: "INVALIDATION_TOPIC_VERSIONS", rowKeyFields: ["topicId"], uniqueFields: ["topicId"], consumers: [ { path: "src/bootstrap/runtime-adapters.ts", token: "indexInvalidationTopicVersions(", }, ], breakingFields: ["topicId", "topicVersion"], }); }); it("projects graph and array exports into deterministic governed rows", async () => { const directory = await mkdtemp( path.join(tmpdir(), "registry-governance-projection-"), ); const artifact = path.join(directory, "registries.json"); try { const result = spawnSync( process.execPath, [ "scripts/check-registries.ts", "--governance", "tests/fixtures/registry/invalidation/governance.json", "--artifact", artifact, "--no-baseline", ], { encoding: "utf8" }, ); expect(result.status, result.stderr).toBe(0); const report = JSON.parse(await readFile(artifact, "utf8")) as { registries: Array<{ registryId: string; rows: Record }>; }; expect( report.registries.find( (registry) => registry.registryId === "FIXTURE-INVALIDATION-EDGES", )?.rows, ).toHaveProperty('["qinv.fixture.changed","orders",1]'); expect( report.registries.find( (registry) => registry.registryId === "FIXTURE-INVALIDATION-EDGES", )?.rows, ).toHaveProperty('["orders","qinv.fixture.changed",1]'); expect( report.registries.find( (registry) => registry.registryId === "FIXTURE-INVALIDATION-VERSIONS", )?.rows, ).toHaveProperty('["qinv.fixture.changed"]'); } finally { await rm(directory, { recursive: true, force: true }); } }); it("rejects duplicate composite invalidation edges after projection", async () => { const directory = await mkdtemp( path.join(tmpdir(), "registry-governance-duplicate-"), ); const artifact = path.join(directory, "registries.json"); try { const result = spawnSync( process.execPath, [ "scripts/check-registries.ts", "--governance", "tests/fixtures/registry/invalidation/duplicate-governance.json", "--artifact", artifact, "--no-baseline", ], { encoding: "utf8" }, ); expect(result.status).toBe(1); const report = JSON.parse(await readFile(artifact, "utf8")) as { failures: string[]; }; expect(report.failures).toEqual([ expect.stringContaining( "duplicates topicId+namespace.namespaceId+namespace.namespaceVersion", ), ]); } finally { await rm(directory, { recursive: true, force: true }); } }); });