/*
Unit tests for conformance covering runConformanceScenario; runConformanceScenario: negative tests; runConformanceScenario: test-only guard.
- Not a contract source of truth — the module under test owns the authoritative behavior; fixtures are minimal scaffolding only.
- RFC-1311: Compass header sweep — declares the conformance suite's contract for test-file scaffold coverage.
*/
import { describe, it, expect, beforeEach } from "vitest";
import {
runConformanceScenario,
buildCatalog,
TEST_MODE_SENTINEL,
type TrustedFixture,
} from "../testing/harness.ts";
import type { ConformanceScenarioV1 } from "../conformance.ts";
import type {
ComponentDeclaration,
ComponentId,
CapabilityId,
ResolvedComponentSetV1,
ResolvedComponentIdentityV1,
} from "@warpgogol/werkstatt-shared/component";
import { computeSetHash } from "../../component/identity.ts";
import type { Sha256Digest } from "@warpgogol/werkstatt-shared/fingerprint";
const VALID_SHA = ("sha256:" + "a".repeat(64)) as Sha256Digest;
function cid(id: string): ComponentId {
return id as ComponentId;
}
function cap(id: string): CapabilityId {
return id as CapabilityId;
}
function makeManifest(overrides: Partial = {}): ComponentDeclaration {
const componentId = overrides.componentId ?? cid("werkstatt/engine");
return {
schema: "werkstatt/component-declaration@1",
componentId,
version: "1.0.0",
artifactHash: VALID_SHA,
scope: "per-workshop",
provides: [
{ capability: cap("werkstatt/kernel"), version: "1.0.0", schemaHash: VALID_SHA as string },
],
requires: [],
requestedGrants: [],
effects: [],
isolation: { tier: 0, adapterId: null },
resources: [{ kind: "cpu", limit: "100ms", owner: componentId, lifecycle: "process" }],
priority: 0,
active: true,
...overrides,
};
}
function makeResolvedIdentity(
overrides: Partial = {},
): ResolvedComponentIdentityV1 {
return {
componentId: cid("werkstatt/engine"),
version: "1.0.0",
artifactHash: VALID_SHA,
...overrides,
};
}
function makeResolvedSet(
overrides: Partial> = {},
): ResolvedComponentSetV1 {
const base: Omit = {
schema: "werkstatt/resolved-component-set@1",
profileId: "site",
components: [makeResolvedIdentity()],
dependencyGraphHash: VALID_SHA as string,
grantSetHash: VALID_SHA as string,
effectPolicyHash: VALID_SHA as string,
isolationPolicyHash: VALID_SHA as string,
...overrides,
};
const setHash = computeSetHash(base);
return { ...base, setHash };
}
function makeTrustedFixture(overrides: Partial = {}): TrustedFixture {
const manifest = makeManifest();
return {
fixtureId: "test-fixture",
artifactHash: VALID_SHA,
trusted: true,
manifests: [manifest],
availableArtifacts: new Map([["werkstatt/engine", VALID_SHA]]),
admittedGrants: [],
...overrides,
};
}
function makeScenario(overrides: Partial = {}): ConformanceScenarioV1 {
const set = makeResolvedSet();
return {
scenarioId: "test-scenario",
fixtureArtifactHash: VALID_SHA as string,
fixtureTrusted: true,
initialSet: set,
desiredSet: set,
injectedEvents: [],
expectedTrace: [],
...overrides,
};
}
beforeEach(() => {
(globalThis as Record)[TEST_MODE_SENTINEL] = true;
});
describe("runConformanceScenario", () => {
it("runs a basic activation scenario and passes", async () => {
const set = makeResolvedSet();
const fixture = makeTrustedFixture();
const scenario = makeScenario({
initialSet: set,
desiredSet: set,
injectedEvents: [],
expectedTrace: [
{
kind: "lifecycle-state",
componentId: cid("werkstatt/engine"),
expectedState: "active",
at: 0,
},
],
});
const result = await runConformanceScenario(scenario, fixture, {
now: () => 0,
drainDeadline: { timeoutMs: 1000 },
});
expect(result.schema).toBe("werkstatt/conformance-result@1");
expect(result.scenarioId).toBe("test-scenario");
expect(result.testOnly).toBe(true);
expect(result.passed).toBe(true);
expect(result.mismatches).toHaveLength(0);
expect(result.violations).toHaveLength(0);
});
it("detects lifecycle-state mismatch", async () => {
const set = makeResolvedSet();
const fixture = makeTrustedFixture();
const scenario = makeScenario({
initialSet: set,
desiredSet: set,
injectedEvents: [
{ type: "fail", componentId: cid("werkstatt/engine"), at: 1, detail: "injected" },
],
expectedTrace: [
{
kind: "lifecycle-state",
componentId: cid("werkstatt/engine"),
expectedState: "active",
at: 2,
},
],
});
const result = await runConformanceScenario(scenario, fixture, {
now: () => 0,
drainDeadline: { timeoutMs: 1000 },
});
expect(result.passed).toBe(false);
expect(result.mismatches).toHaveLength(1);
expect(result.mismatches[0]!.expected).toBe("active");
expect(result.mismatches[0]!.actual).toBe("failed");
});
it("detects capability-callable mismatch", async () => {
const set = makeResolvedSet();
const fixture = makeTrustedFixture();
const scenario = makeScenario({
initialSet: set,
desiredSet: set,
injectedEvents: [{ type: "drain", componentId: cid("werkstatt/engine"), at: 1 }],
expectedTrace: [
{
kind: "capability-callable",
componentId: cid("werkstatt/engine"),
callable: true,
at: 2,
},
],
});
const result = await runConformanceScenario(scenario, fixture, {
now: () => 0,
drainDeadline: { timeoutMs: 100 },
});
expect(result.passed).toBe(false);
expect(result.mismatches).toHaveLength(1);
expect(result.mismatches[0]!.expected).toBe("true");
expect(result.mismatches[0]!.actual).toBe("false");
});
it("records injected failures", async () => {
const set = makeResolvedSet();
const fixture = makeTrustedFixture();
const scenario = makeScenario({
initialSet: set,
desiredSet: set,
injectedEvents: [
{ type: "fail", componentId: cid("werkstatt/engine"), at: 1, detail: "crash" },
],
expectedTrace: [
{
kind: "lifecycle-state",
componentId: cid("werkstatt/engine"),
expectedState: "failed",
at: 2,
},
],
});
const result = await runConformanceScenario(scenario, fixture, {
now: () => 0,
drainDeadline: { timeoutMs: 1000 },
});
expect(result.injectedFailures).toHaveLength(1);
expect(result.injectedFailures[0]).toContain("crash");
expect(result.passed).toBe(true);
});
it("handles quarantine events", async () => {
const set = makeResolvedSet();
const fixture = makeTrustedFixture();
const scenario = makeScenario({
initialSet: set,
desiredSet: set,
injectedEvents: [{ type: "quarantine", componentId: cid("werkstatt/engine"), at: 1 }],
expectedTrace: [
{
kind: "lifecycle-state",
componentId: cid("werkstatt/engine"),
expectedState: "quarantined",
at: 2,
},
],
});
const result = await runConformanceScenario(scenario, fixture, {
now: () => 0,
drainDeadline: { timeoutMs: 1000 },
});
expect(result.passed).toBe(true);
expect(result.cleanupReport.quarantined).toContain("werkstatt/engine");
});
it("produces cleanup report with correct component lists", async () => {
const set = makeResolvedSet();
const fixture = makeTrustedFixture();
const scenario = makeScenario({
initialSet: set,
desiredSet: set,
injectedEvents: [],
expectedTrace: [],
});
const result = await runConformanceScenario(scenario, fixture, {
now: () => 0,
drainDeadline: { timeoutMs: 1000 },
});
expect(result.cleanupReport).toBeDefined();
expect(result.cleanupReport.disposed).toEqual([]);
expect(result.cleanupReport.quarantined).toEqual([]);
expect(result.cleanupReport.failed).toEqual([]);
});
it("terminal state is mixed when components differ", async () => {
const manifestA = makeManifest({ componentId: cid("werkstatt/alpha") });
const manifestB = makeManifest({
componentId: cid("werkstatt/beta"),
provides: [
{
capability: cap("werkstatt/beta-cap"),
version: "1.0.0",
schemaHash: VALID_SHA as string,
},
],
});
const identityA = makeResolvedIdentity({ componentId: cid("werkstatt/alpha") });
const identityB = makeResolvedIdentity({
componentId: cid("werkstatt/beta"),
artifactHash: VALID_SHA,
});
const set = makeResolvedSet({ components: [identityA, identityB] });
const fixture = makeTrustedFixture({
manifests: [manifestA, manifestB],
availableArtifacts: new Map([
["werkstatt/alpha", VALID_SHA],
["werkstatt/beta", VALID_SHA],
]),
});
const scenario = makeScenario({
initialSet: set,
desiredSet: set,
injectedEvents: [{ type: "fail", componentId: cid("werkstatt/alpha"), at: 1 }],
expectedTrace: [],
});
const result = await runConformanceScenario(scenario, fixture, {
now: () => 0,
drainDeadline: { timeoutMs: 1000 },
});
expect(result.terminalState).toBe("mixed");
});
});
describe("runConformanceScenario: negative tests", () => {
it("rejects untrusted fixture", async () => {
const set = makeResolvedSet();
const fixture = { ...makeTrustedFixture(), trusted: false } as unknown as TrustedFixture;
const scenario = makeScenario({ initialSet: set, desiredSet: set });
await expect(
runConformanceScenario(scenario, fixture as TrustedFixture, {
now: () => 0,
drainDeadline: { timeoutMs: 1000 },
}),
).rejects.toThrow(/CONFORMANCE-02/);
});
it("rejects fixture with unpinned artifact hash", async () => {
const set = makeResolvedSet();
const fixture = makeTrustedFixture({ artifactHash: "unpinned" });
const scenario = makeScenario({
initialSet: set,
desiredSet: set,
fixtureArtifactHash: "unpinned",
});
await expect(
runConformanceScenario(scenario, fixture, {
now: () => 0,
drainDeadline: { timeoutMs: 1000 },
}),
).rejects.toThrow(/CONFORMANCE-03/);
});
it("rejects scenario/fixture hash mismatch", async () => {
const set = makeResolvedSet();
const fixture = makeTrustedFixture();
const scenario = makeScenario({
initialSet: set,
desiredSet: set,
fixtureArtifactHash: ("sha256:" + "f".repeat(64)) as string,
});
await expect(
runConformanceScenario(scenario, fixture, {
now: () => 0,
drainDeadline: { timeoutMs: 1000 },
}),
).rejects.toThrow(/CONFORMANCE-04/);
});
});
describe("runConformanceScenario: test-only guard", () => {
it("rejects invocation outside test mode", async () => {
(globalThis as Record)[TEST_MODE_SENTINEL] = false;
const set = makeResolvedSet();
const fixture = makeTrustedFixture();
const scenario = makeScenario({ initialSet: set, desiredSet: set });
await expect(
runConformanceScenario(scenario, fixture, {
now: () => 0,
drainDeadline: { timeoutMs: 1000 },
}),
).rejects.toThrow(/CONFORMANCE-01/);
});
});
describe("buildCatalog", () => {
it("builds a catalog from active set, manifests, and observations", () => {
const set = makeResolvedSet();
const manifests = new Map([
["werkstatt/engine", makeManifest()],
]);
const observations = new Map([
["werkstatt/engine", { componentId: cid("werkstatt/engine"), lifecycleState: "active" }],
]);
const catalog = buildCatalog(set, manifests, observations);
expect(catalog.schema).toBe("werkstatt/capability-catalog@1");
expect(catalog.resolvedComponentSetHash).toBe(set.setHash);
expect(catalog.entries).toHaveLength(1);
expect(catalog.entries[0]!.callable).toBe(true);
});
});
describe("conformance result contract", () => {
it("result is always marked testOnly", async () => {
const set = makeResolvedSet();
const fixture = makeTrustedFixture();
const scenario = makeScenario({ initialSet: set, desiredSet: set });
const result = await runConformanceScenario(scenario, fixture, {
now: () => 0,
drainDeadline: { timeoutMs: 1000 },
});
expect(result.testOnly).toBe(true);
});
it("result contains no admission or promotion decision", async () => {
const set = makeResolvedSet();
const fixture = makeTrustedFixture();
const scenario = makeScenario({ initialSet: set, desiredSet: set });
const result = await runConformanceScenario(scenario, fixture, {
now: () => 0,
drainDeadline: { timeoutMs: 1000 },
});
const keys = Object.keys(result);
expect(keys).not.toContain("admission");
expect(keys).not.toContain("promotion");
expect(keys).not.toContain("certified");
expect(keys).not.toContain("authority");
});
});