import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import { test, expect } from "vitest"; import { runAdrValidate } from "../adr/index.ts"; import type { KernelCommandInput, KernelLogger, KernelRuntimeContext, } from "@warpgogol/werkstatt-shared/kernel"; import { createDefaultIO } from "@warpgogol/werkstatt-shared/kernel"; /* Regression coverage for ADR validation rules that need both docs/adrs and docs/rfcs fixture state. Not a contract source of truth — the module under test owns the authoritative behavior; fixtures are minimal scaffolding only. Fixtures stay inline and minimal so each case states its own setup. RFC-1311: carried legacy entry — Post-refactor hardening: cover cross-domain ADR supersession by RFC id. */ // @ai-invariant fixtures must not couple to internals beyond the public surface under test const noopLogger: KernelLogger = { section() {}, info() {}, warn() {}, error() {}, success() {}, event() {}, getEvents() { return []; }, }; function ctx(workspaceRoot: string): KernelRuntimeContext { return { workspaceRoot, siteExplicit: false, logger: noopLogger, dryRun: false, outputFormat: "json", io: createDefaultIO().io, actualState: undefined as never, }; } const input: KernelCommandInput = { argv: [], flags: {} }; function adr(supersededBy: string): string { return `--- id: ADR-9001 title: "Fixture ADR" status: superseded scope: workspace decider: architecture createdAt: 2026-07-09 updatedAt: 2026-07-09 implementedAt: 2026-07-09 closedAt: 2026-07-09 supersedes: [] supersededBy: ${supersededBy} related: [] reviewers: - human:andrii-syrokomskyi --- # ADR-9001: Fixture ADR ## Context x ## Decision x ## Justification x ## Consequences x ## Evolution x `; } function rfc(id: string): string { return `--- id: ${id} title: "Fixture RFC" status: implemented kind: architecture scope: workspace owners: - architecture reviewers: - human:andrii-syrokomskyi createdAt: 2026-07-09 updatedAt: 2026-07-09 implementedAt: 2026-07-09 closedAt: supersedes: [] supersededBy: amends: [] amendedBy: [] related: [] satisfies: - DNA-35 commands: proposed: [] added: [] changed: [] removed: [] appsImpacted: [] packagesImpacted: [] successSignals: [] nonGoals: [] --- # ${id}: Fixture RFC ## Context x ## Problem x ## Decision x ## Architectural fit x ## Design x ## Rollout x ## Alternatives considered x ## Risks x ## Acceptance criteria - [ ] a - [ ] b - [ ] c ## Implementation notes for agents x `; } async function setup(files: Record): Promise { const root = await fs.mkdtemp(path.join(os.tmpdir(), "adr-validate-")); for (const [name, content] of Object.entries(files)) { const target = path.join(root, name); await fs.mkdir(path.dirname(target), { recursive: true }); await fs.writeFile(target, content, "utf8"); } return root; } test("adr.validate allows a superseded ADR to point at an existing RFC", async () => { const root = await setup({ "docs/adrs/adr-9001-fixture-adr.md": adr("RFC-9002"), "docs/rfcs/rfc-9002-fixture-rfc.md": rfc("RFC-9002"), }); try { const result = await runAdrValidate(input, ctx(root)); expect(result.data?.violations ?? []).toEqual([]); } finally { await fs.rm(root, { recursive: true, force: true }); } }); test("adr.validate rejects a superseded ADR pointing at a missing RFC", async () => { const root = await setup({ "docs/adrs/adr-9001-fixture-adr.md": adr("RFC-9999"), }); try { const result = await runAdrValidate(input, ctx(root)); expect((result.data?.violations ?? []).some((v: { rule?: string }) => v.rule === "AV-09")).toBe( true, ); } finally { await fs.rm(root, { recursive: true, force: true }); } });