import { describe, expect, it } from "vitest";
import { sha256Hex } from "./contract/hash.js";
import type { ConformInput, ConformResult } from "./conform.js";
import {
PROVE_DEFAULT_MAX_PASSES,
PROVE_MAX_PASSES,
type ProveSamplerArgs,
clampMaxPasses,
emptyConformResult,
proveCompliant,
proveIssueCount,
resolveProveVerdict,
} from "./conform-prove.js";
// ── conform stubs ─────────────────────────────────────────────────────────
function clean(code: string): ConformResult {
return {
conformed: code,
changed: false,
summary: "clean",
changes: [],
suggestions: [],
unresolved: [],
};
}
const oneChange: ConformResult["changes"] = [
{
kind: "replace-token",
ruleId: "styles/no-raw-color",
code: "FUI6001",
severity: "warning",
message: "Replaced hardcoded color.",
before: "#2563eb",
after: "var(--brand-600)",
confidence: "high",
},
];
const oneSuggestion: ConformResult["suggestions"] = [
{ kind: "review-low-confidence", message: "Ambiguous variant.", confidence: "medium" },
];
/** Replaces a raw color once, then is clean — the canonical 2-pass convergence. */
function tokenizing(input: ConformInput): ConformResult {
if (input.code.includes("#2563eb")) {
return {
conformed: input.code.replace("#2563eb", "var(--brand-600)"),
changed: true,
summary: "Mapped one hardcoded value.",
changes: oneChange,
suggestions: [],
unresolved: [],
};
}
return clean(input.code);
}
/** Always stalls (no deterministic change) with one residual suggestion. */
function residual(input: ConformInput): ConformResult {
return {
conformed: input.code,
changed: false,
summary: "Needs review.",
changes: [],
suggestions: oneSuggestion,
unresolved: [],
};
}
describe("proveCompliant — pure validate-fix-validate primitive", () => {
it("loops deterministic fixes until a clean pass proves compliance", async () => {
const out = await proveCompliant(
{ code: '
Send
' },
{ conform: tokenizing }
);
expect(out.verdict).toBe("pass");
expect(out.provedCompliant).toBe(true);
expect(out.issueCount).toBe(0);
expect(out.corrections).toBe(1);
expect(out.changed).toBe(true);
expect(out.conformed).toContain("var(--brand-600)");
expect(out.passHistory.map((p) => ({ pass: p.pass, issues: p.issues }))).toEqual([
{ pass: 1, issues: 1 },
{ pass: 2, issues: 0 },
]);
expect(out.reason).toBe("0 findings after 2 passes.");
});
it("certifies a clean-on-first-pass result with no coverage signal", async () => {
const out = await proveCompliant({ code: "hi
" }, { conform: (i) => clean(i.code) });
expect(out).toMatchObject({ verdict: "pass", provedCompliant: true, issueCount: 0 });
expect(out.passHistory).toHaveLength(1);
expect(out.reason).toBe("0 findings after 1 pass.");
expect(out.changed).toBe(false);
});
it("returns insufficient_coverage (NOT pass) for a clean run over an empty catalog", async () => {
const out = await proveCompliant(
{ code: "hi
" },
{
conform: (i) => ({
...clean(i.code),
coverage: { tokens: 0, components: 0, evaluated: false },
}),
}
);
expect(out.verdict).toBe("insufficient_coverage");
expect(out.provedCompliant).toBe(false);
expect(out.issueCount).toBe(0);
expect(out.reason).toContain("could not be evaluated");
});
it("fails with residual findings when no sampler is provided", async () => {
const out = await proveCompliant({ code: "" }, { conform: residual });
expect(out.verdict).toBe("fail");
expect(out.issueCount).toBe(1);
expect(out.reason).toBe("no sampler was available and residual issues remain.");
expect(out.residual.suggestions).toHaveLength(1);
});
it("does not sample when allowSampling is false", async () => {
let sampled = false;
const out = await proveCompliant(
{ code: "" },
{
conform: residual,
sampler: () => {
sampled = true;
return null;
},
},
{ allowSampling: false }
);
expect(sampled).toBe(false);
expect(out.verdict).toBe("fail");
expect(out.reason).toBe("sampling was disabled and residual issues remain.");
});
it("uses the sampler for residual issues and re-validates the sampled code", async () => {
const out = await proveCompliant(
{ code: "" },
{
conform: (i) => (i.code.includes("aria-label") ? clean(i.code) : residual(i)),
sampler: () => ({
code: '',
model: "test-model",
}),
}
);
expect(out.verdict).toBe("pass");
expect(out.conformed).toBe('');
expect(out.passHistory[0]?.sampling).toMatchObject({
requested: true,
used: true,
model: "test-model",
});
expect(out.passHistory).toHaveLength(2);
});
it("does NOT accept a sampled fix that still has residual findings", async () => {
const out = await proveCompliant(
{ code: "" },
{
// Sampler returns a different-but-still-broken snippet; conform never
// reaches clean, so the loop must not certify compliance.
conform: (i) => residual(i),
sampler: ({ code }) => ({ code: `${code}\n{/* attempt */}` }),
},
{ maxPasses: 3 }
);
expect(out.verdict).toBe("fail");
expect(out.provedCompliant).toBe(false);
expect(out.issueCount).toBe(1);
});
it("counts a declining sampler (null) as used:false and fails", async () => {
const out = await proveCompliant({ code: "" }, { conform: residual, sampler: () => null });
expect(out.verdict).toBe("fail");
expect(out.passHistory[0]?.sampling).toMatchObject({ requested: true, used: false });
});
it("threads (pass, seq, codeHashAtRequest) into the sampler across rounds", async () => {
const seen: ProveSamplerArgs["metadata"][] = [];
const codesSampled: string[] = [];
await proveCompliant(
{ code: "ROUND0" },
{
conform: (i) => residual(i), // always stalls -> sampler invoked each round
sampler: ({ code, metadata }) => {
seen.push(metadata);
codesSampled.push(code);
return { code: `ROUND${metadata.seq + 1}` }; // always a fresh snippet
},
},
{ maxPasses: 4 }
);
// maxPasses 4 -> sampler fires at seq 0,1,2 (cap is samplingAttempts < maxPasses-1)
expect(seen.map((m) => m.seq)).toEqual([0, 1, 2]);
expect(seen.map((m) => m.pass)).toEqual([1, 2, 3]);
// codeHashAtRequest is the real SHA-256 of the code the sampler saw.
expect(seen.map((m) => m.codeHashAtRequest)).toEqual(codesSampled.map((c) => sha256Hex(c)));
expect(seen[0]?.codeHashAtRequest).toBe(sha256Hex("ROUND0"));
expect(seen[1]?.codeHashAtRequest).toBe(sha256Hex("ROUND1"));
});
it("stops at maxPasses when deterministic fixes keep producing findings", async () => {
let calls = 0;
const out = await proveCompliant(
{ code: "raw" },
{
conform: (i) => {
calls += 1;
return {
conformed: `${i.code}\n/* ${calls} */`,
changed: true,
summary: "still dirty",
changes: oneChange,
suggestions: [],
unresolved: [],
};
},
},
{ maxPasses: 2 }
);
expect(calls).toBe(2);
expect(out.verdict).toBe("fail");
expect(out.passHistory).toHaveLength(2);
expect(out.corrections).toBe(2);
expect(out.reason).toBe("stopped after 2 passes with 1 finding(s).");
});
it("is deterministic — identical inputs produce identical results", async () => {
const run = () =>
proveCompliant(
{ code: 'Send
' },
{ conform: tokenizing }
);
expect(await run()).toEqual(await run());
});
});
describe("prove primitive helpers", () => {
it("proveIssueCount sums changes + suggestions + unresolved", () => {
expect(proveIssueCount(clean("x"))).toBe(0);
expect(proveIssueCount(residual({ code: "x" }))).toBe(1);
});
it("emptyConformResult is a neutral, unchanged result", () => {
const r = emptyConformResult("abc");
expect(r).toMatchObject({ conformed: "abc", changed: false });
expect(proveIssueCount(r)).toBe(0);
});
it("resolveProveVerdict: coverage trumps everything", () => {
expect(resolveProveVerdict({ coverageEvaluated: false, provedCompliant: true })).toBe(
"insufficient_coverage"
);
expect(resolveProveVerdict({ coverageEvaluated: true, provedCompliant: true })).toBe("pass");
expect(resolveProveVerdict({ coverageEvaluated: true, provedCompliant: false })).toBe("fail");
});
it("clampMaxPasses clamps to 1..8 and defaults non-numbers to 4", () => {
expect(clampMaxPasses(0)).toBe(1);
expect(clampMaxPasses(1)).toBe(1);
expect(clampMaxPasses(4)).toBe(PROVE_DEFAULT_MAX_PASSES);
expect(clampMaxPasses(8)).toBe(PROVE_MAX_PASSES);
expect(clampMaxPasses(99)).toBe(PROVE_MAX_PASSES);
expect(clampMaxPasses(3.7)).toBe(3);
expect(clampMaxPasses(undefined)).toBe(PROVE_DEFAULT_MAX_PASSES);
expect(clampMaxPasses(Number.NaN)).toBe(PROVE_DEFAULT_MAX_PASSES);
});
});