Files
tech-log-frontend/tests/unit/runbook-contract.test.ts
T

54 lines
1.5 KiB
TypeScript

import { readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";
type RunbookSpecification = Readonly<{
triggerKinds: string[];
containment: string;
window: string;
escalation: string[];
recoveryEvidence: string[];
negativeFixture: string;
gateId: string;
}>;
type RunbookDocument = Readonly<{
runbooks: Record<string, RunbookSpecification>;
}>;
describe("operational runbook contract", () => {
const document = JSON.parse(
readFileSync("config/runbooks/runbooks.json", "utf8"),
) as RunbookDocument;
it("defines all five runbooks with four machine-checkable contract axes", () => {
expect(Object.keys(document.runbooks)).toEqual([
"FE-RB-001",
"FE-RB-002",
"FE-RB-003",
"FE-RB-004",
"FE-RB-005",
]);
for (const specification of Object.values(document.runbooks)) {
expect(specification.triggerKinds.length).toBeGreaterThan(0);
expect(specification.containment).toEqual(expect.any(String));
expect(specification.window).toEqual(expect.any(String));
expect(specification.escalation.length).toBeGreaterThanOrEqual(2);
expect(specification.recoveryEvidence).toHaveLength(4);
expect(specification.negativeFixture).toEqual(expect.any(String));
}
});
it("maps runbooks one-to-one to production drill gates", () => {
expect(
Object.values(document.runbooks).map((runbook) => runbook.gateId),
).toEqual([
"FE-GATE-021",
"FE-GATE-022",
"FE-GATE-023",
"FE-GATE-024",
"FE-GATE-025",
]);
});
});