a11oy / __tests__ /adversarial /axis_collision.test.ts
betterwithage's picture
sync(space): complete build context — fix BUILD_ERROR (CTO)
518343a verified
Raw
History Blame
11.2 kB
/**
* axis_collision.test.ts
* Doctrine v6 R3 — Vertical Governance Receipts
* 10 Axis-Collision adversarial tests
*
* Tests for conflicts, contradictions, and impossible combinations across
* Λ-axis assignments in policy documents. Collision scenarios include:
* - Same clause mapping to conflicting axes
* - mandatory_axes referencing axes not present in any clause
* - Axis weight distribution violations (e.g., all weights = 0)
* - Cross-policy axis coverage below minimum_lambda_coverage
* - mandatory axis appearing only with enforcement: "informational"
*
* Some of these MUST be detected at the policy_loader level (semantic validation),
* since JSON Schema alone cannot express cross-field semantic constraints.
*
* Test framework: Jest / ts-jest
* Run: npx jest tests/adversarial/axis_collision.test.ts
*/
import Ajv from "ajv";
import addFormats from "ajv-formats";
import * as fs from "fs";
import * as path from "path";
const SCHEMA_PATH = path.resolve(__dirname, "../../a11oy-knowledge.schema.json");
function buildValidator() {
const ajv = new Ajv({ allErrors: true, strict: false });
addFormats(ajv);
const schema = JSON.parse(fs.readFileSync(SCHEMA_PATH, "utf8"));
return ajv.compile(schema);
}
/** Compute distinct Λ-axes covered by all clauses */
function coveredAxes(clauses: any[]): Set<string> {
const axes = new Set<string>();
for (const c of clauses) {
for (const m of c.lambda_axes ?? []) axes.add(m.axis);
}
return axes;
}
/** Semantic check: mandatory_axes must be covered by clauses */
function mandatoryAxesCovered(policy: any): boolean {
const covered = coveredAxes(policy.regulatory_clauses ?? []);
const mandatory: string[] = policy.compliance_thresholds?.mandatory_axes ?? [];
return mandatory.every((ax) => covered.has(ax));
}
/** Semantic check: covered axis count ≥ minimum_lambda_coverage */
function coverageAboveMinimum(policy: any): boolean {
const covered = coveredAxes(policy.regulatory_clauses ?? []);
return covered.size >= (policy.compliance_thresholds?.minimum_lambda_coverage ?? 0);
}
/**
* Semantic check: EVERY mandatory axis must carry at least one mandatory
* enforcement mapping. Returns false if any axis listed in mandatory_axes is
* either never mapped or appears only with non-mandatory enforcement
* (informational / recommended). The earlier implementation returned true on
* the first mandatory axis that happened to have a mandatory mapping, which
* masked the case where a different mandatory axis had been downgraded.
*/
function mandatoryAxisHasMandatoryEnforcement(policy: any): boolean {
const mandatory = new Set<string>(policy.compliance_thresholds?.mandatory_axes ?? []);
if (mandatory.size === 0) return true;
const axisHasMandatoryMapping = new Map<string, boolean>();
for (const ax of mandatory) axisHasMandatoryMapping.set(ax, false);
for (const clause of policy.regulatory_clauses ?? []) {
for (const mapping of clause.lambda_axes ?? []) {
if (mandatory.has(mapping.axis) && mapping.enforcement === "mandatory") {
axisHasMandatoryMapping.set(mapping.axis, true);
}
}
}
for (const ax of mandatory) {
if (!axisHasMandatoryMapping.get(ax)) return false;
}
return true;
}
function basePolicy(): any {
return {
schema_version: "1.0.0",
vertical: "energy",
regime: "NERC-CIP/FERC-887",
effective_date: "2025-07-01",
jurisdiction: "US-FERC/NERC",
meta: {
title: "Axis collision base policy for adversarial testing",
description: "Policy used for axis collision adversarial scenario testing.",
authority: "NERC CIP-002 through CIP-014; FERC Order No. 887",
receipt_chain_required: true,
merkle_root_algorithm: "SHA3-256",
},
regulatory_clauses: Array.from({ length: 8 }, (_, i) => ({
clause_id: `NERC-COL-${String(i + 1).padStart(3, "0")}`,
title: `Collision test clause ${i + 1}`,
citation: `18 CFR § 40.${i + 1}`,
full_ref: `18 C.F.R. § 40.${i + 1} — axis collision test clause with full reference detail`,
lambda_axes: [
{ axis: "Λ6", label: "Security", weight: 0.9, enforcement: "mandatory",
rationale: "BES Cyber System protection requires mandatory security receipt logging." },
{ axis: "Λ7", label: "Auditability", weight: 0.85, enforcement: "mandatory",
rationale: "CIP-007-6 audit log tamper-evidence via Merkle DAG." },
],
})),
compliance_thresholds: {
minimum_lambda_coverage: 7,
mandatory_axes: ["Λ5", "Λ6", "Λ7"],
receipt_retention_days: 2190,
},
receipt_chain: {
algorithm: "SHA3-256",
chaining: "merkle_dag",
quorum: "2-of-3",
nodes: ["primary", "air-gapped-ot", "regulatory-archive"],
},
};
}
describe("Adversarial — Axis Collision (10 tests)", () => {
const validate = buildValidator();
// AC-001: mandatory_axes include Λ5 but no clause maps to Λ5 — semantic violation
test("AC-001: mandatory axis Λ5 not covered by any clause — semantic violation detected", () => {
const p = basePolicy();
// All clauses only cover Λ6, Λ7 — Λ5 is mandatory but uncovered
// Schema accepts this; semantic check must reject
expect(validate(p)).toBe(true); // Schema: OK
expect(mandatoryAxesCovered(p)).toBe(false); // Semantic: FAIL
});
// AC-002: minimum_lambda_coverage = 5 but only 2 distinct axes present — coverage gap
test("AC-002: covered axes (2) < minimum_lambda_coverage (5) — semantic violation", () => {
const p = basePolicy();
p.compliance_thresholds.minimum_lambda_coverage = 5;
// Clauses cover only Λ6 and Λ7 (2 axes) — below minimum 5
expect(validate(p)).toBe(true);
expect(coverageAboveMinimum(p)).toBe(false);
});
// AC-003: Same clause maps same Λ-axis twice (duplicate axis in lambda_axes)
test("AC-003: duplicate Λ7 in same clause lambda_axes — schema accepts, loader must deduplicate", () => {
const p = basePolicy();
p.regulatory_clauses[0].lambda_axes = [
{ axis: "Λ7", label: "Auditability", weight: 1.0, enforcement: "mandatory",
rationale: "First mapping for Λ7 in this clause for deduplication test." },
{ axis: "Λ7", label: "Auditability", weight: 0.5, enforcement: "recommended",
rationale: "Second mapping for Λ7 — duplicate with conflicting weight." },
];
// Schema allows up to 4 axis mappings per clause without uniqueItems constraint on axis
expect(validate(p)).toBe(true);
// Loader must detect and reject or merge duplicate axis mappings
const dup = p.regulatory_clauses[0].lambda_axes.filter((m: any) => m.axis === "Λ7");
expect(dup.length).toBe(2); // Two mappings to same axis — collision detected
});
// AC-004: mandatory axis appearing ONLY with enforcement "informational" — enforcement gap
test("AC-004: mandatory axis Λ6 only with informational enforcement — enforcement collision", () => {
const p = basePolicy();
// Change all Λ6 mappings to informational
for (const clause of p.regulatory_clauses) {
for (const m of clause.lambda_axes) {
if (m.axis === "Λ6") m.enforcement = "informational";
}
}
expect(validate(p)).toBe(true); // Schema accepts any enforcement value
expect(mandatoryAxisHasMandatoryEnforcement(p)).toBe(false); // Semantic fail
});
// AC-005: All weights set to 0.0 — zero-weight mandatory axis
test("AC-005: all lambda weights = 0.0 — policy carries no compliance signal", () => {
const p = basePolicy();
for (const clause of p.regulatory_clauses) {
for (const m of clause.lambda_axes) { m.weight = 0.0; }
}
expect(validate(p)).toBe(true); // Schema: 0.0 is valid minimum
// Compute total weight for mandatory axes
const totalMandatoryWeight = p.regulatory_clauses
.flatMap((c: any) => c.lambda_axes)
.filter((m: any) => m.enforcement === "mandatory")
.reduce((sum: number, m: any) => sum + m.weight, 0);
expect(totalMandatoryWeight).toBe(0); // Semantic warning: all mandatory weights zero
});
// AC-006: minimum_lambda_coverage > 10 (impossible — only 10 axes exist)
test("AC-006: minimum_lambda_coverage = 11 exceeds available axes (schema rejects > 10)", () => {
const p = basePolicy();
p.compliance_thresholds.minimum_lambda_coverage = 11;
expect(validate(p)).toBe(false); // Schema enforces maximum: 10
});
// AC-007: Label mismatch — axis "Λ1" labeled "Privacy" (Λ3's label)
test("AC-007: Λ1 axis labeled 'Privacy' — axis↔label mismatch (schema accepts, loader rejects)", () => {
const p = basePolicy();
p.regulatory_clauses[0].lambda_axes.push({
axis: "Λ1",
label: "Privacy", // Correct label for Λ1 is "Transparency"
weight: 0.5,
enforcement: "recommended",
rationale: "Incorrect label test for axis-label collision detection scenario.",
});
expect(validate(p)).toBe(true); // Schema: both "Λ1" and "Privacy" are valid enum values
// Policy loader must validate axis↔label coherence using the axis-label map
});
// AC-008: Cross-vertical vertical+regime mismatch (healthcare vertical with SOX regime)
test("AC-008: vertical 'healthcare' with regime 'SOX/Dodd-Frank' — semantic mismatch", () => {
const p = basePolicy();
p.vertical = "healthcare";
p.regime = "SOX/Dodd-Frank";
expect(validate(p)).toBe(true); // Schema: no cross-field constraint
// Loader must check vertical↔regime coherence matrix
});
// AC-009: receipt_chain quorum 5-of-3 (quorum numerator > denominator — impossible)
test("AC-009: quorum '5-of-3' (impossible — 5 signatures from 3 nodes) is accepted by schema pattern", () => {
const p = basePolicy();
p.receipt_chain.quorum = "5-of-3";
// Pattern ^\d+-of-\d+$ matches — schema accepts
expect(validate(p)).toBe(true);
// Extract and validate quorum numerically
const [n, d] = p.receipt_chain.quorum.split("-of-").map(Number);
expect(n).toBeGreaterThan(d); // Semantic violation: impossible quorum
});
// AC-010: mandatory_axes contains Λ10 but jurisdiction is "US-Federal" (no sovereignty concern)
test("AC-010: Λ10 (Sovereignty) mandatory for domestic US-Federal jurisdiction — semantic question", () => {
const p = basePolicy();
p.jurisdiction = "US-Federal";
p.compliance_thresholds.mandatory_axes = ["Λ5", "Λ6", "Λ7", "Λ10"];
// Schema: no constraint — passes
expect(validate(p)).toBe(true);
// Loader may issue warning: Λ10 (Sovereignty) is typically relevant for
// cross-border/international jurisdictions. Flagging for human review.
const hasSovereignty = p.compliance_thresholds.mandatory_axes.includes("Λ10");
const isInternational = !p.jurisdiction.startsWith("US-Federal");
// Not an error but a review flag
if (hasSovereignty && !isInternational) {
// Expect loader to emit a WARNING (not error) for sovereignty axis on domestic regime
expect(true).toBe(true); // test documents the pattern
}
});
});