/*
Unit tests for external edit guard covering its documented public contract and regression-sensitive edge cases.
- Not a contract source of truth — the module under test owns the authoritative behavior; fixtures are minimal scaffolding only.
- RFC-0520: initial unit tests for Bordbuch-vs-git-log external edit guard.
- ADR-0093: treat the register birth commit as pipeline-authored in the external-edit guard
*/
import { test, expect } from "vitest";
import { evaluateExternalEditGate } from "./external-edit-guard.ts";
const systemId = "test-system";
test("empty Bordbuch, empty git log → verdict: pass", () => {
const result = evaluateExternalEditGate({
systemId,
bordbuchEntries: [],
gitLogShas: [],
rangeShas: [],
});
expect(result.verdict).toBe("pass");
expect(result.violations).toHaveLength(0);
});
test("Bordbuch has reconcile SHA, git log matches → verdict: pass", () => {
const result = evaluateExternalEditGate({
systemId,
bordbuchEntries: [{ kind: "mission-reconcile", metadata: { commitSha: "abc123" } }],
gitLogShas: ["abc123"],
rangeShas: [],
});
expect(result.verdict).toBe("pass");
});
test("git log has SHA not in Bordbuch → verdict: fail, rule: external-edit-detected", () => {
const result = evaluateExternalEditGate({
systemId,
bordbuchEntries: [{ kind: "mission-reconcile", metadata: { commitSha: "abc123" } }],
gitLogShas: ["abc123", "def456"],
rangeShas: [],
});
expect(result.verdict).toBe("fail");
expect(result.violations).toHaveLength(1);
expect(result.violations[0]!.rule).toBe("external-edit-detected");
expect(result.violations[0]!.message).toContain("1 commit(s)");
expect(result.violations[0]!.message).toContain("def456");
});
test("Bordbuch has reconcile entry with rangeShas, all SHAs accounted for → verdict: pass", () => {
const result = evaluateExternalEditGate({
systemId,
bordbuchEntries: [
{ kind: "mission-reconcile", metadata: { commitSha: "abc123", preReconcileSha: "pre000" } },
],
gitLogShas: ["abc123", "range1", "range2"],
rangeShas: ["range1", "range2"],
});
expect(result.verdict).toBe("pass");
});
test("git log has SHAs in range but also extra SHAs → verdict: fail", () => {
const result = evaluateExternalEditGate({
systemId,
bordbuchEntries: [
{ kind: "mission-reconcile", metadata: { commitSha: "abc123", preReconcileSha: "pre000" } },
],
gitLogShas: ["abc123", "range1", "range2", "extra999"],
rangeShas: ["range1", "range2"],
});
expect(result.verdict).toBe("fail");
expect(result.violations[0]!.message).toContain("extra999");
});
// ADR-0091: externalEditBaselineSha grandfathering
test("baseline SHA grandfathers itself and all older commits → verdict: pass", () => {
const result = evaluateExternalEditGate({
systemId,
bordbuchEntries: [{ kind: "mission-reconcile", metadata: { commitSha: "new001" } }],
// rev-list order: newest-first — old001..old003 pre-date Bordbuch tracing
gitLogShas: ["new001", "base00", "old001", "old002", "old003"],
rangeShas: [],
externalEditBaselineSha: "base00",
});
expect(result.verdict).toBe("pass");
expect(result.violations).toHaveLength(0);
});
test("baseline SHA with newer untraced commit → fail reports only the newer commit", () => {
const result = evaluateExternalEditGate({
systemId,
bordbuchEntries: [{ kind: "mission-reconcile", metadata: { commitSha: "new001" } }],
gitLogShas: ["untraced", "new001", "base00", "old001", "old002"],
rangeShas: [],
externalEditBaselineSha: "base00",
});
expect(result.verdict).toBe("fail");
expect(result.violations).toHaveLength(1);
expect(result.violations[0]!.rule).toBe("external-edit-detected");
expect(result.violations[0]!.message).toContain("1 commit(s)");
expect(result.violations[0]!.message).toContain("untraced");
expect(result.violations[0]!.message).not.toContain("old001");
});
test("baseline SHA as newest commit → entire history grandfathered → verdict: pass", () => {
const result = evaluateExternalEditGate({
systemId,
bordbuchEntries: [],
gitLogShas: ["base00", "old001", "old002"],
rangeShas: [],
externalEditBaselineSha: "base00",
});
expect(result.verdict).toBe("pass");
});
test("baseline SHA absent from rev-list → external-edit-baseline-missing violation", () => {
const result = evaluateExternalEditGate({
systemId,
bordbuchEntries: [{ kind: "mission-reconcile", metadata: { commitSha: "abc123" } }],
gitLogShas: ["abc123"],
rangeShas: [],
externalEditBaselineSha: "missing0",
});
expect(result.verdict).toBe("fail");
expect(result.violations).toHaveLength(1);
expect(result.violations[0]!.rule).toBe("external-edit-baseline-missing");
expect(result.violations[0]!.message).toContain("missing0");
});
test("no baseline → untraced legacy history still flagged (unchanged behavior)", () => {
const result = evaluateExternalEditGate({
systemId,
bordbuchEntries: [{ kind: "mission-reconcile", metadata: { commitSha: "abc123" } }],
gitLogShas: ["abc123", "legacy1", "legacy2"],
rangeShas: [],
});
expect(result.verdict).toBe("fail");
expect(result.violations[0]!.rule).toBe("external-edit-detected");
expect(result.violations[0]!.message).toContain("2 commit(s)");
});
// ADR-0093: mergedShas tracing
test("mergedShas[] traces every merged workpiece commit → verdict: pass", () => {
const result = evaluateExternalEditGate({
systemId,
bordbuchEntries: [
{
kind: "mission-reconcile",
metadata: { commitSha: "merge01", mergedShas: ["wp001", "wp002", "wp003"] },
},
],
gitLogShas: ["merge01", "wp001", "wp002", "wp003"],
rangeShas: [],
});
expect(result.verdict).toBe("pass");
expect(result.violations).toHaveLength(0);
});
test("mergedShas[] entry plus an untraced commit → fail reports only the untraced one", () => {
const result = evaluateExternalEditGate({
systemId,
bordbuchEntries: [
{
kind: "mission-reconcile",
metadata: { commitSha: "merge01", mergedShas: ["wp001", "wp002"] },
},
],
gitLogShas: ["merge01", "wp001", "wp002", "extern1"],
rangeShas: [],
});
expect(result.verdict).toBe("fail");
expect(result.violations).toHaveLength(1);
expect(result.violations[0]!.rule).toBe("external-edit-detected");
expect(result.violations[0]!.message).toContain("1 commit(s)");
expect(result.violations[0]!.message).toContain("extern1");
});
test("legacy entry without mergedShas → only commitSha traced (unchanged behavior)", () => {
const result = evaluateExternalEditGate({
systemId,
bordbuchEntries: [{ kind: "mission-reconcile", metadata: { commitSha: "merge01" } }],
gitLogShas: ["merge01", "wp001"],
rangeShas: [],
});
expect(result.verdict).toBe("fail");
expect(result.violations[0]!.message).toContain("wp001");
});
test("mergedShas[] on a non-mission-reconcile kind is ignored", () => {
const result = evaluateExternalEditGate({
systemId,
bordbuchEntries: [
{ kind: "deployment", metadata: { mergedShas: ["wp001"] } },
{ kind: "mission-reconcile", metadata: { commitSha: "merge01" } },
],
gitLogShas: ["merge01", "wp001"],
rangeShas: [],
});
expect(result.verdict).toBe("fail");
expect(result.violations[0]!.message).toContain("wp001");
});
test("multiple reconcile entries accumulate mergedShas across missions", () => {
const result = evaluateExternalEditGate({
systemId,
bordbuchEntries: [
{ kind: "mission-reconcile", metadata: { commitSha: "merge01", mergedShas: ["wp001"] } },
{
kind: "mission-reconcile",
metadata: { commitSha: "merge02", mergedShas: ["wp002", "wp003"] },
},
],
gitLogShas: ["merge02", "wp002", "wp003", "merge01", "wp001"],
rangeShas: [],
});
expect(result.verdict).toBe("pass");
});
test("the sternsystem.register birth commit is pipeline-authored → verdict: pass", () => {
const result = evaluateExternalEditGate({
systemId,
bordbuchEntries: [],
gitLogShas: ["e6031e0"],
gitLogSubjects: ["sternsystem.register: scaffold dp7"],
rangeShas: [],
});
expect(result.verdict).toBe("pass");
});