Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions packages/@eep-dev/compliance-cli/src/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
* helper. It is the same wiring as `tests/conformance-fixtures.test.ts`,
* lifted into the published package.
*/
import Ajv, { type ValidateFunction } from 'ajv';
// Schemas are JSON Schema 2020-12; Ajv's default export only
// understands draft-07, so the 2020-12 build is required.
import Ajv2020, { type ValidateFunction } from 'ajv/dist/2020.js';
import addFormats from 'ajv-formats';
import { readdirSync, readFileSync, statSync, existsSync } from 'node:fs';
import { join, resolve, dirname } from 'node:path';
Expand Down Expand Up @@ -87,7 +89,7 @@ export function loadSchemaRegistry(explicitDir?: string): SchemaRegistry | null
const dir = findSchemasDir(explicitDir);
if (!dir) return null;

const ajv = new Ajv({ strict: false, allErrors: true, allowUnionTypes: true });
const ajv = new Ajv2020({ strict: false, allErrors: true, allowUnionTypes: true });
addFormats(ajv);

const byFile = new Map<string, unknown>();
Expand Down
22 changes: 11 additions & 11 deletions packages/@eep-dev/gates/src/g-a1-a8.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,23 +206,23 @@ describe('A4 — audit-log.json: delivery audit log schema and SPECIFICATION §1
}
});

it('defines AuditEntry in definitions', () => {
expect(schema.definitions).toHaveProperty('AuditEntry');
it('defines AuditEntry in $defs', () => {
expect(schema.$defs).toHaveProperty('AuditEntry');
});

it('AuditEntry has all required fields including signature', () => {
const required = schema.definitions.AuditEntry.required as string[];
const required = schema.$defs.AuditEntry.required as string[];
for (const f of ['entry_id', 'event_type', 'actor_did', 'publisher_did', 'timestamp', 'outcome', 'signature']) {
expect(required).toContain(f);
}
});

it('entry_id is UUID format', () => {
expect(schema.definitions.AuditEntry.properties.entry_id.format).toBe('uuid');
expect(schema.$defs.AuditEntry.properties.entry_id.format).toBe('uuid');
});

it('event_type covers 5 major categories', () => {
const types = schema.definitions.AuditEntry.properties.event_type.enum as string[];
const types = schema.$defs.AuditEntry.properties.event_type.enum as string[];
expect(types.some(t => t.startsWith('gate.'))).toBe(true);
expect(types.some(t => t.startsWith('session.'))).toBe(true);
expect(types.some(t => t.startsWith('webhook.'))).toBe(true);
Expand All @@ -231,26 +231,26 @@ describe('A4 — audit-log.json: delivery audit log schema and SPECIFICATION §1
});

it('event_type includes gate.proof.accepted and gate.proof.rejected', () => {
const types = schema.definitions.AuditEntry.properties.event_type.enum as string[];
const types = schema.$defs.AuditEntry.properties.event_type.enum as string[];
expect(types).toContain('gate.proof.accepted');
expect(types).toContain('gate.proof.rejected');
});

it('event_type includes PoI validation events', () => {
const types = schema.definitions.AuditEntry.properties.event_type.enum as string[];
const types = schema.$defs.AuditEntry.properties.event_type.enum as string[];
expect(types).toContain('poi.validated');
expect(types).toContain('poi.rejected');
});

it('actor_did and publisher_did have DID pattern validation', () => {
const actorPattern = schema.definitions.AuditEntry.properties.actor_did.pattern;
const publisherPattern = schema.definitions.AuditEntry.properties.publisher_did.pattern;
const actorPattern = schema.$defs.AuditEntry.properties.actor_did.pattern;
const publisherPattern = schema.$defs.AuditEntry.properties.publisher_did.pattern;
expect(actorPattern).toContain('did:');
expect(publisherPattern).toContain('did:');
});

it('outcome is constrained enum', () => {
const outcomes = schema.definitions.AuditEntry.properties.outcome.enum as string[];
const outcomes = schema.$defs.AuditEntry.properties.outcome.enum as string[];
expect(outcomes).toContain('success');
expect(outcomes).toContain('failure');
});
Expand All @@ -265,7 +265,7 @@ describe('A4 — audit-log.json: delivery audit log schema and SPECIFICATION §1
expect(example).toHaveProperty(f);
}
const entry = example.entries[0];
for (const f of schema.definitions.AuditEntry.required) {
for (const f of schema.$defs.AuditEntry.required) {
expect(entry).toHaveProperty(f);
}
});
Expand Down
20 changes: 10 additions & 10 deletions packages/@eep-dev/gates/src/g-b1-b10.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ describe('B4 — data.withdrawal.json: REST endpoint schema for GDPR erasure', (

it('WithdrawalRequest definition has all required fields', () => {
const schema = loadSchema('data.withdrawal.json') as any;
const required: string[] = schema.definitions.WithdrawalRequest.required;
const required: string[] = schema.$defs.WithdrawalRequest.required;
expect(required).toContain('claim_id');
expect(required).toContain('agent_did');
expect(required).toContain('reason');
Expand All @@ -201,7 +201,7 @@ describe('B4 — data.withdrawal.json: REST endpoint schema for GDPR erasure', (

it('WithdrawalRequest reason enum includes GDPR and CCPA bases', () => {
const schema = loadSchema('data.withdrawal.json') as any;
const reasons: string[] = schema.definitions.WithdrawalRequest.properties.reason.enum;
const reasons: string[] = schema.$defs.WithdrawalRequest.properties.reason.enum;
expect(reasons).toContain('gdpr_erasure');
expect(reasons).toContain('ccpa_deletion');
expect(reasons).toContain('revoke_consent');
Expand All @@ -210,7 +210,7 @@ describe('B4 — data.withdrawal.json: REST endpoint schema for GDPR erasure', (

it('WithdrawalAcknowledgement response covers 202 Accepted scenario', () => {
const schema = loadSchema('data.withdrawal.json') as any;
const ack = schema.definitions.WithdrawalAcknowledgement;
const ack = schema.$defs.WithdrawalAcknowledgement;
expect(ack).toBeDefined();
const required: string[] = ack.required;
expect(required).toContain('withdrawal_id');
Expand All @@ -221,7 +221,7 @@ describe('B4 — data.withdrawal.json: REST endpoint schema for GDPR erasure', (

it('WithdrawalAcknowledgement status enum includes all lifecycle states', () => {
const schema = loadSchema('data.withdrawal.json') as any;
const statuses: string[] = schema.definitions.WithdrawalAcknowledgement.properties.status.enum;
const statuses: string[] = schema.$defs.WithdrawalAcknowledgement.properties.status.enum;
expect(statuses).toContain('pending');
expect(statuses).toContain('processing');
expect(statuses).toContain('completed');
Expand All @@ -230,7 +230,7 @@ describe('B4 — data.withdrawal.json: REST endpoint schema for GDPR erasure', (

it('data.withdrawal.json describes 24-hour publisher commitment (Whitepaper §7.3)', () => {
const schema = loadSchema('data.withdrawal.json') as any;
const desc: string = schema.definitions.WithdrawalAcknowledgement.properties.expected_completion_at.description;
const desc: string = schema.$defs.WithdrawalAcknowledgement.properties.expected_completion_at.description;
expect(desc).toContain('24 hours');
expect(desc.toLowerCase()).toContain('whitepaper');
});
Expand Down Expand Up @@ -279,7 +279,7 @@ describe('B6 — eep.dev Registry API: registry.search-result.json schema', () =

it('RegistryEntry has trust_score field (0.0–1.0) as per Whitepaper §4.2', () => {
const schema = loadSchema('registry.search-result.json') as any;
const entry = schema.definitions.RegistryEntry;
const entry = schema.$defs.RegistryEntry;
expect(entry).toBeDefined();
expect(entry.properties.trust_score).toBeDefined();
expect(entry.properties.trust_score.minimum).toBe(0.0);
Expand All @@ -288,7 +288,7 @@ describe('B6 — eep.dev Registry API: registry.search-result.json schema', () =

it('RegistryEntry.conformance_tier only allows Core/Standard/Full/unverified', () => {
const schema = loadSchema('registry.search-result.json') as any;
const tiers: string[] = schema.definitions.RegistryEntry.properties.conformance_tier.enum;
const tiers: string[] = schema.$defs.RegistryEntry.properties.conformance_tier.enum;
expect(tiers).toContain('Core');
expect(tiers).toContain('Standard');
expect(tiers).toContain('Full');
Expand All @@ -298,7 +298,7 @@ describe('B6 — eep.dev Registry API: registry.search-result.json schema', () =

it('RegistryEntry supports filtering by gate_types and layers', () => {
const schema = loadSchema('registry.search-result.json') as any;
const entry = schema.definitions.RegistryEntry;
const entry = schema.$defs.RegistryEntry;
expect(entry.properties.gate_types).toBeDefined();
expect(entry.properties.layers).toBeDefined();
expect(entry.properties.categories).toBeDefined();
Expand All @@ -307,7 +307,7 @@ describe('B6 — eep.dev Registry API: registry.search-result.json schema', () =
it('RegistryEntry supports federation (registry_source + resolved_from)', () => {
const schema = loadSchema('registry.search-result.json') as any;
expect(schema.properties.resolved_from).toBeDefined();
const entry = schema.definitions.RegistryEntry;
const entry = schema.$defs.RegistryEntry;
expect(entry.properties.registry_source).toBeDefined();
});
});
Expand Down Expand Up @@ -447,7 +447,7 @@ describe('Cross-cutting: schema count and consistency', () => {
const newSchemas = ['data.withdrawal.json', 'registry.search-result.json'];
for (const schemaName of newSchemas) {
const schema = loadSchema(schemaName) as any;
expect(schema.$schema).toBe('http://json-schema.org/draft-07/schema#');
expect(schema.$schema).toBe('https://json-schema.org/draft/2020-12/schema');
expect(schema.$id).toContain('https://eep.dev/schemas/v0.1/');
}
});
Expand Down
4 changes: 2 additions & 2 deletions packages/@eep-dev/gates/src/g13-g22.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -573,14 +573,14 @@ describe('Proof validator: new types in batch validation', () => {

it('proof type pattern includes data_request and agreement in gate.proof.json', () => {
const schema = loadSchema('gate.proof.json') as any;
const pattern = schema.definitions.proof.properties.type.pattern;
const pattern = schema.$defs.proof.properties.type.pattern;
expect(pattern).toContain('data_request');
expect(pattern).toContain('agreement');
});

it('gate.config.json type pattern includes data_request and agreement', () => {
const schema = loadSchema('gate.config.json') as any;
const pattern = schema.definitions.requirement.properties.type.pattern;
const pattern = schema.$defs.requirement.properties.type.pattern;
expect(pattern).toContain('data_request');
expect(pattern).toContain('agreement');
});
Expand Down
2 changes: 1 addition & 1 deletion packages/@eep-dev/gates/src/g37-g39.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ describe('G39 — EEPConformanceCredential JSON Schema', () => {
});

it('has correct $schema and $id', () => {
expect(conformanceCredentialSchema.$schema).toBe('http://json-schema.org/draft-07/schema#');
expect(conformanceCredentialSchema.$schema).toBe('https://json-schema.org/draft/2020-12/schema');
expect(conformanceCredentialSchema.$id).toMatch(/conformance\.credential\.json/);
});

Expand Down
Loading