2026-08-03 08:48:39 -07:00
|
|
|
import { describe, test } from 'node:test';
|
|
|
|
|
import assert from 'node:assert/strict';
|
|
|
|
|
import { DSLCompiler } from '../src/DSLCompiler.js';
|
|
|
|
|
|
|
|
|
|
function createMockArbiter() {
|
|
|
|
|
const relationConfigs = new Map();
|
|
|
|
|
return {
|
|
|
|
|
relationConfigs,
|
|
|
|
|
setRelationConfig(relation, config) {
|
|
|
|
|
relationConfigs.set(relation, config);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
describe('Integration Tests', () => {
|
|
|
|
|
const arbiter = createMockArbiter();
|
|
|
|
|
const compiler = new DSLCompiler(arbiter);
|
|
|
|
|
|
|
|
|
|
test('Complete authorization system', () => {
|
|
|
|
|
const completeSystem = `
|
|
|
|
|
// Type definitions with complex behaviors
|
2026-08-03 09:12:20 -07:00
|
|
|
definition Employee {
|
|
|
|
|
role: Role
|
|
|
|
|
group: Group
|
2026-08-03 08:48:39 -07:00
|
|
|
isActive: boolean
|
|
|
|
|
lastActive: timestamp BEHAVES {
|
|
|
|
|
decaying down hourly
|
|
|
|
|
} CACHE lazy
|
|
|
|
|
isSuspended: boolean
|
|
|
|
|
balance: number BEHAVES {
|
|
|
|
|
decaying down hourly
|
|
|
|
|
} CACHE eager
|
|
|
|
|
score: number BEHAVES {
|
|
|
|
|
blurring adaptive confidence_95
|
|
|
|
|
} CACHE lazy
|
|
|
|
|
session: string BEHAVES {
|
|
|
|
|
ttl 24h
|
|
|
|
|
} CACHE eager
|
|
|
|
|
clearance: string BEHAVES {
|
|
|
|
|
blurring fixed
|
|
|
|
|
} CACHE eager
|
|
|
|
|
reputation: number BEHAVES {
|
|
|
|
|
decaying up daily
|
|
|
|
|
} CACHE lazy
|
2026-08-03 09:12:20 -07:00
|
|
|
activityScore: number
|
|
|
|
|
verificationLevel: number
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
definition Role {
|
|
|
|
|
permissions: Permission[]
|
|
|
|
|
clearance: string
|
2026-08-03 08:48:39 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
definition Group {
|
|
|
|
|
name: string
|
|
|
|
|
permissions: Permission[]
|
|
|
|
|
level: string
|
2026-08-03 09:12:20 -07:00
|
|
|
clearance: string
|
2026-08-03 08:48:39 -07:00
|
|
|
isPublic: boolean CACHE eager
|
|
|
|
|
created: timestamp BEHAVES {
|
|
|
|
|
decaying stable monthly
|
|
|
|
|
} CACHE lazy
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
definition Permission {
|
|
|
|
|
name: string
|
|
|
|
|
level: string
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-03 08:48:39 -07:00
|
|
|
definition Document {
|
|
|
|
|
level: string
|
2026-08-03 09:12:20 -07:00
|
|
|
owner: Employee
|
2026-08-03 08:48:39 -07:00
|
|
|
tags: string[]
|
|
|
|
|
content: string BEHAVES {
|
|
|
|
|
blurring fixed
|
|
|
|
|
} CACHE lazy
|
|
|
|
|
accessCount: number BEHAVES {
|
|
|
|
|
decaying up daily
|
|
|
|
|
} CACHE eager
|
|
|
|
|
expiresAt: timestamp BEHAVES {
|
|
|
|
|
ttl 30d
|
|
|
|
|
} CACHE eager
|
|
|
|
|
isPublic: boolean CACHE eager
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
definition Resource {
|
|
|
|
|
level: string
|
2026-08-03 09:12:20 -07:00
|
|
|
owner: Employee
|
2026-08-03 08:48:39 -07:00
|
|
|
permissions: Permission[]
|
|
|
|
|
isPublic: boolean CACHE eager
|
|
|
|
|
accessCount: number BEHAVES {
|
|
|
|
|
decaying up daily
|
|
|
|
|
} CACHE eager
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Facts with various properties and caching
|
2026-08-03 09:12:20 -07:00
|
|
|
fact hasRole(user: Employee, role: string) CACHE eager
|
|
|
|
|
fact isMember(user: any, group: any) transitive CACHE lazy limit 10
|
|
|
|
|
fact isFriend(user: any, friend: any) symmetrical CACHE eager limit 100
|
|
|
|
|
fact owns(user: Employee, doc: Document) CACHE eager
|
|
|
|
|
fact isSuspended(user: Employee) CACHE lazy
|
|
|
|
|
fact hasPermission(user: Employee, resource: Resource, action: string) CACHE eager
|
|
|
|
|
fact isAdmin(user: Employee) CACHE eager
|
|
|
|
|
fact isOwner(user: Employee, resource: Resource) CACHE eager
|
|
|
|
|
fact hasAccess(user: Employee, resource: Resource, level: string) CACHE lazy
|
|
|
|
|
fact isColleague(user: any, colleague: any) symmetrical CACHE lazy limit 50
|
|
|
|
|
fact isParentOf(parent: Employee, child: Employee) transitive CACHE eager limit 3
|
2026-08-03 11:34:52 -07:00
|
|
|
fact reachable(user: any, doc: any) CACHE lazy
|
2026-08-03 09:12:20 -07:00
|
|
|
fact hasClearance(user: Employee, level: string) CACHE eager
|
|
|
|
|
fact parentOf(user: any, parent: any) CACHE eager
|
|
|
|
|
fact similar(a: any, b: any) CACHE lazy
|
|
|
|
|
fact isActive(user: Employee) CACHE eager
|
|
|
|
|
fact isTrusted(user: Employee) CACHE eager
|
|
|
|
|
fact isBlacklisted(user: Employee) CACHE lazy
|
|
|
|
|
fact hasRecentActivity(user: Employee) CACHE lazy
|
|
|
|
|
fact recentlyActive(user: Employee) CACHE lazy
|
2026-08-03 08:48:39 -07:00
|
|
|
|
|
|
|
|
// Evidence rules with complex logic
|
2026-08-03 09:12:20 -07:00
|
|
|
evidence canRead(user: Employee, doc: Document) {
|
2026-08-03 08:48:39 -07:00
|
|
|
owns(user, doc)
|
|
|
|
|
|
|
|
|
|
isMember(user, *group) {
|
2026-08-03 11:34:52 -07:00
|
|
|
reachable(group, doc)
|
2026-08-03 08:48:39 -07:00
|
|
|
} limit 5
|
|
|
|
|
|
|
|
|
|
parentOf(user, *parent) {
|
2026-08-03 11:34:52 -07:00
|
|
|
reachable(parent, doc)
|
2026-08-03 08:48:39 -07:00
|
|
|
} limit 3
|
|
|
|
|
|
|
|
|
|
similar(doc, *similar) |similarity| {
|
2026-08-03 11:34:52 -07:00
|
|
|
reachable(user, similar)
|
2026-08-03 09:12:20 -07:00
|
|
|
} limit 5 with similarity > 0.7
|
2026-08-03 08:48:39 -07:00
|
|
|
|
|
|
|
|
WHEN hasRole(user, 'admin') UNLESS isSuspended(user)
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
evidence canWrite(user: Employee, doc: Document) {
|
2026-08-03 08:48:39 -07:00
|
|
|
owns(user, doc)
|
|
|
|
|
|
|
|
|
|
isMember(user, *group) {
|
2026-08-03 11:34:52 -07:00
|
|
|
reachable(group, doc)
|
2026-08-03 08:48:39 -07:00
|
|
|
} limit 3
|
|
|
|
|
|
|
|
|
|
WHEN hasRole(user, 'admin') UNLESS isSuspended(user)
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
REQUIRES isActive(user)
|
2026-08-03 08:48:39 -07:00
|
|
|
}
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
evidence canDelete(user: Employee, doc: Document) {
|
2026-08-03 08:48:39 -07:00
|
|
|
owns(user, doc)
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
ALWAYS isActive(user)
|
2026-08-03 08:48:39 -07:00
|
|
|
|
|
|
|
|
WHEN hasRole(user, 'admin') UNLESS isSuspended(user)
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
REQUIRES isActive(user)
|
2026-08-03 08:48:39 -07:00
|
|
|
}
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
evidence canAccessCritical(user: Employee, resource: Resource) {
|
2026-08-03 08:48:39 -07:00
|
|
|
fusion min {
|
2026-08-03 09:12:20 -07:00
|
|
|
hasClearance(user, resource.level),
|
|
|
|
|
isActive(user),
|
|
|
|
|
NOT isBlacklisted(user)
|
2026-08-03 08:48:39 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fusion max {
|
|
|
|
|
hasRole(user, 'admin')
|
2026-08-03 09:12:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fusion majority {
|
|
|
|
|
hasClearance(user, 'secret'),
|
|
|
|
|
isTrusted(user),
|
|
|
|
|
recentlyActive(user)
|
2026-08-03 08:48:39 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
evidence canAccessSensitive(user: Employee, doc: Document) {
|
|
|
|
|
ALWAYS isActive(user)
|
2026-08-03 08:48:39 -07:00
|
|
|
|
|
|
|
|
WHEN hasRole(user, 'admin') UNLESS isSuspended(user)
|
|
|
|
|
|
|
|
|
|
REQUIRES hasClearance(user, doc.level)
|
|
|
|
|
|
|
|
|
|
fusion majority {
|
2026-08-03 09:12:20 -07:00
|
|
|
isTrusted(user),
|
|
|
|
|
hasRecentActivity(user)
|
2026-08-03 08:48:39 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Measures for computed values
|
2026-08-03 09:12:20 -07:00
|
|
|
measure userRole(user: Employee) {
|
2026-08-03 08:48:39 -07:00
|
|
|
user.role
|
|
|
|
|
} PROVIDES string
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
measure userPermissions(user: Employee) {
|
2026-08-03 08:48:39 -07:00
|
|
|
fusion max {
|
2026-08-03 09:12:20 -07:00
|
|
|
user.role.permissions,
|
2026-08-03 08:48:39 -07:00
|
|
|
user.group.permissions
|
|
|
|
|
}
|
2026-08-03 09:12:20 -07:00
|
|
|
} PROVIDES Permission
|
2026-08-03 08:48:39 -07:00
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
measure effectiveClearance(user: Employee) {
|
2026-08-03 08:48:39 -07:00
|
|
|
fusion majority {
|
2026-08-03 09:12:20 -07:00
|
|
|
user.clearance,
|
|
|
|
|
user.role.clearance,
|
2026-08-03 08:48:39 -07:00
|
|
|
user.group.clearance
|
|
|
|
|
}
|
|
|
|
|
} PROVIDES string
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
measure userTrustScore(user: Employee) {
|
2026-08-03 08:48:39 -07:00
|
|
|
fusion average {
|
2026-08-03 09:12:20 -07:00
|
|
|
user.reputation,
|
|
|
|
|
user.activityScore,
|
2026-08-03 08:48:39 -07:00
|
|
|
user.verificationLevel
|
|
|
|
|
}
|
|
|
|
|
} PROVIDES number
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
measure userBalance(user: Employee) {
|
2026-08-03 08:48:39 -07:00
|
|
|
user.balance
|
|
|
|
|
} PROVIDES number
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
measure userScore(user: Employee) {
|
2026-08-03 08:48:39 -07:00
|
|
|
user.score
|
|
|
|
|
} PROVIDES number
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const result = compiler.compile(completeSystem, 'test-complete-system');
|
|
|
|
|
assert.ok(result.success, 'Complete authorization system should compile successfully');
|
|
|
|
|
assert.ok(result.program.definitions.length >= 4, 'Should have multiple definitions');
|
|
|
|
|
assert.ok(result.program.facts.length >= 10, 'Should have multiple facts');
|
|
|
|
|
assert.ok(result.program.evidence.length >= 5, 'Should have multiple evidence rules');
|
|
|
|
|
assert.ok(result.program.measures.length >= 6, 'Should have multiple measures');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('Multi-domain system', () => {
|
|
|
|
|
const multiDomain = `
|
|
|
|
|
// Authentication domain
|
2026-08-03 09:12:20 -07:00
|
|
|
definition Employee {
|
2026-08-03 08:48:39 -07:00
|
|
|
role: string
|
|
|
|
|
isActive: boolean
|
|
|
|
|
lastActive: timestamp BEHAVES { decaying down hourly } CACHE lazy
|
|
|
|
|
session: string BEHAVES { ttl 24h } CACHE eager
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
fact hasRole(user: Employee, role: string) CACHE eager
|
|
|
|
|
fact isActive(user: Employee) CACHE eager
|
|
|
|
|
fact recentlyActive(user: any) CACHE lazy
|
|
|
|
|
fact isPublic(doc: any) CACHE eager
|
2026-08-03 08:48:39 -07:00
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
evidence canAuthenticate(user: Employee) {
|
|
|
|
|
isActive(user)
|
|
|
|
|
recentlyActive(user)
|
2026-08-03 08:48:39 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Authorization domain
|
|
|
|
|
definition Resource {
|
|
|
|
|
level: string
|
2026-08-03 09:12:20 -07:00
|
|
|
owner: Employee
|
2026-08-03 08:48:39 -07:00
|
|
|
permissions: Permission[]
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
definition Permission {
|
|
|
|
|
name: string
|
|
|
|
|
level: string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fact owns(user: Employee, resource: Resource) CACHE eager
|
|
|
|
|
fact hasPermission(user: Employee, resource: Resource, action: string) CACHE eager
|
2026-08-03 08:48:39 -07:00
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
evidence canAccess(user: Employee, resource: Resource) {
|
2026-08-03 08:48:39 -07:00
|
|
|
owns(user, resource)
|
|
|
|
|
hasPermission(user, resource, 'read')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Finance domain
|
2026-08-03 09:12:20 -07:00
|
|
|
definition Tenant {
|
2026-08-03 08:48:39 -07:00
|
|
|
balance: number BEHAVES { decaying down hourly } CACHE eager
|
2026-08-03 09:12:20 -07:00
|
|
|
owner: Employee
|
2026-08-03 08:48:39 -07:00
|
|
|
isActive: boolean CACHE eager
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
fact hasAccount(user: Employee, account: Tenant) CACHE eager
|
|
|
|
|
fact hasBalance(user: Employee, amount: number) CACHE eager
|
2026-08-03 08:48:39 -07:00
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
evidence canWithdraw(user: Employee, amount: number) {
|
2026-08-03 08:48:39 -07:00
|
|
|
hasBalance(user, amount)
|
2026-08-03 09:12:20 -07:00
|
|
|
isActive(user)
|
2026-08-03 08:48:39 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Social domain
|
|
|
|
|
definition Group {
|
|
|
|
|
name: string
|
2026-08-03 09:12:20 -07:00
|
|
|
members: Employee[]
|
2026-08-03 08:48:39 -07:00
|
|
|
isPublic: boolean CACHE eager
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
fact isMember(user: any, group: any) transitive CACHE lazy limit 10
|
|
|
|
|
fact isFriend(user: any, friend: any) symmetrical CACHE eager limit 100
|
2026-08-03 08:48:39 -07:00
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
evidence canAccessGroup(user: Employee, group: Group) {
|
2026-08-03 08:48:39 -07:00
|
|
|
isMember(user, group)
|
2026-08-03 09:12:20 -07:00
|
|
|
isPublic(group)
|
2026-08-03 08:48:39 -07:00
|
|
|
}
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const result = compiler.compile(multiDomain, 'test-multi-domain');
|
|
|
|
|
assert.ok(result.success, 'Multi-domain system should compile successfully');
|
|
|
|
|
assert.ok(result.program.definitions.length >= 4, 'Should have multiple domain definitions');
|
|
|
|
|
assert.ok(result.program.facts.length >= 8, 'Should have multiple domain facts');
|
|
|
|
|
assert.ok(result.program.evidence.length >= 4, 'Should have multiple domain evidence rules');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('Hierarchical access', () => {
|
|
|
|
|
const hierarchicalSystem = `
|
2026-08-03 09:12:20 -07:00
|
|
|
definition Employee {
|
2026-08-03 08:48:39 -07:00
|
|
|
role: string
|
|
|
|
|
level: string
|
|
|
|
|
isActive: boolean
|
|
|
|
|
clearance: string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
definition Organization {
|
|
|
|
|
name: string
|
|
|
|
|
level: string
|
|
|
|
|
parent: Organization
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
definition Resource {
|
|
|
|
|
level: string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fact isMember(user: any, org: any) transitive CACHE lazy limit 5
|
2026-08-03 08:48:39 -07:00
|
|
|
fact isParentOf(parent: Organization, child: Organization) transitive CACHE eager limit 3
|
2026-08-03 11:34:52 -07:00
|
|
|
fact reachable(user: any, doc: any) CACHE lazy
|
2026-08-03 09:12:20 -07:00
|
|
|
fact hasRole(user: Employee, role: string) CACHE eager
|
|
|
|
|
fact hasClearance(user: Employee, level: string) CACHE eager
|
|
|
|
|
fact isSuspended(user: any) CACHE lazy
|
|
|
|
|
fact parentOf(user: any, parent: any) CACHE eager
|
2026-08-03 08:48:39 -07:00
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
evidence canAccessOrg(user: Employee, org: Organization) {
|
2026-08-03 08:48:39 -07:00
|
|
|
isMember(user, org)
|
|
|
|
|
|
|
|
|
|
isParentOf(org, *parentOrg) {
|
2026-08-03 11:34:52 -07:00
|
|
|
reachable(user, parentOrg)
|
2026-08-03 08:48:39 -07:00
|
|
|
} limit 3
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
WHEN hasRole(user, 'admin') UNLESS isSuspended(user)
|
2026-08-03 08:48:39 -07:00
|
|
|
}
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
evidence canAccessResource(user: Employee, resource: Resource) {
|
2026-08-03 08:48:39 -07:00
|
|
|
isMember(user, *org) {
|
2026-08-03 11:34:52 -07:00
|
|
|
reachable(org, resource)
|
2026-08-03 08:48:39 -07:00
|
|
|
} limit 5
|
|
|
|
|
|
|
|
|
|
parentOf(user, *parent) {
|
2026-08-03 11:34:52 -07:00
|
|
|
reachable(parent, resource)
|
2026-08-03 08:48:39 -07:00
|
|
|
} limit 2
|
|
|
|
|
}
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const result = compiler.compile(hierarchicalSystem, 'test-hierarchical');
|
|
|
|
|
assert.ok(result.success, 'Hierarchical access system should compile successfully');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('Similarity-based access', () => {
|
|
|
|
|
const similaritySystem = `
|
2026-08-03 09:12:20 -07:00
|
|
|
definition Employee {
|
2026-08-03 08:48:39 -07:00
|
|
|
profile: string
|
|
|
|
|
interests: string[]
|
|
|
|
|
isActive: boolean
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
definition Document {
|
|
|
|
|
content: string
|
|
|
|
|
tags: string[]
|
|
|
|
|
isPublic: boolean
|
2026-08-03 09:12:20 -07:00
|
|
|
owner: Employee
|
2026-08-03 08:48:39 -07:00
|
|
|
}
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
fact isFriend(user: any, friend: any) symmetrical CACHE eager limit 100
|
|
|
|
|
fact hasInterest(user: any, interest: string) CACHE lazy
|
|
|
|
|
fact hasTag(doc: any, tag: string) CACHE lazy
|
|
|
|
|
fact owns(user: any, doc: any) CACHE eager
|
2026-08-03 11:34:52 -07:00
|
|
|
fact reachable(user: any, doc: any) CACHE lazy
|
2026-08-03 09:12:20 -07:00
|
|
|
fact similar(a: any, b: any) CACHE lazy
|
|
|
|
|
fact isPublic(doc: any) CACHE eager
|
|
|
|
|
fact hasInterests(user: any) CACHE lazy
|
|
|
|
|
fact hasTags(doc: any) CACHE lazy
|
|
|
|
|
fact hasProfile(user: any) CACHE lazy
|
|
|
|
|
fact hasContent(doc: any) CACHE lazy
|
2026-08-03 08:48:39 -07:00
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
evidence canRead(user: Employee, doc: Document) {
|
2026-08-03 08:48:39 -07:00
|
|
|
owns(user, doc)
|
|
|
|
|
|
|
|
|
|
similar(doc, *similar) |similarity| {
|
2026-08-03 11:34:52 -07:00
|
|
|
reachable(user, similar)
|
2026-08-03 09:12:20 -07:00
|
|
|
isPublic(similar)
|
|
|
|
|
} limit 10 with similarity > 0.7
|
2026-08-03 08:48:39 -07:00
|
|
|
|
|
|
|
|
isFriend(user, *friend) {
|
2026-08-03 11:34:52 -07:00
|
|
|
reachable(friend, doc)
|
2026-08-03 08:48:39 -07:00
|
|
|
} limit 5
|
|
|
|
|
|
|
|
|
|
fusion majority {
|
2026-08-03 09:12:20 -07:00
|
|
|
hasInterests(user),
|
|
|
|
|
hasTags(doc)
|
2026-08-03 08:48:39 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
evidence canRecommend(user: Employee, doc: Document) {
|
2026-08-03 08:48:39 -07:00
|
|
|
similar(user, *similarUser) |similarity| {
|
2026-08-03 11:34:52 -07:00
|
|
|
reachable(similarUser, doc)
|
2026-08-03 09:12:20 -07:00
|
|
|
} limit 20 with similarity > 0.8
|
2026-08-03 08:48:39 -07:00
|
|
|
|
|
|
|
|
fusion average {
|
2026-08-03 09:12:20 -07:00
|
|
|
hasProfile(user),
|
|
|
|
|
hasContent(doc)
|
2026-08-03 08:48:39 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const result = compiler.compile(similaritySystem, 'test-similarity');
|
|
|
|
|
assert.ok(result.success, 'Similarity-based access system should compile successfully');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('Temporal access', () => {
|
|
|
|
|
const temporalSystem = `
|
2026-08-03 09:12:20 -07:00
|
|
|
definition Employee {
|
2026-08-03 08:48:39 -07:00
|
|
|
lastActive: timestamp BEHAVES { decaying down hourly } CACHE lazy
|
|
|
|
|
session: string BEHAVES { ttl 24h } CACHE eager
|
|
|
|
|
isActive: boolean
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
definition Event {
|
|
|
|
|
startTime: timestamp
|
|
|
|
|
endTime: timestamp
|
|
|
|
|
isPublic: boolean
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
fact hasAccess(user: Employee, event: Event) CACHE lazy
|
|
|
|
|
fact isParticipant(user: Employee, event: Event) CACHE eager
|
|
|
|
|
fact recentlyActive(user: any) CACHE lazy
|
|
|
|
|
fact sessionFresh(user: any) CACHE lazy
|
|
|
|
|
fact isPublic(doc: any) CACHE eager
|
|
|
|
|
fact isSuspended(user: any) CACHE lazy
|
|
|
|
|
fact isActive(user: any) CACHE eager
|
2026-08-03 08:48:39 -07:00
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
evidence canAccessEvent(user: Employee, event: Event) {
|
|
|
|
|
recentlyActive(user)
|
2026-08-03 08:48:39 -07:00
|
|
|
|
|
|
|
|
isParticipant(user, event)
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
WHEN isPublic(event) UNLESS isSuspended(user)
|
2026-08-03 08:48:39 -07:00
|
|
|
|
|
|
|
|
fusion min {
|
2026-08-03 09:12:20 -07:00
|
|
|
sessionFresh(user),
|
|
|
|
|
isActive(user)
|
2026-08-03 08:48:39 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
evidence canAccessHistorical(user: Employee, event: Event) {
|
|
|
|
|
recentlyActive(user)
|
2026-08-03 08:48:39 -07:00
|
|
|
|
|
|
|
|
fusion majority {
|
2026-08-03 09:12:20 -07:00
|
|
|
isActive(user),
|
|
|
|
|
sessionFresh(user),
|
|
|
|
|
isPublic(event)
|
2026-08-03 08:48:39 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const result = compiler.compile(temporalSystem, 'test-temporal');
|
|
|
|
|
assert.ok(result.success, 'Temporal access system should compile successfully');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('Complex behaviors', () => {
|
|
|
|
|
const behaviorSystem = `
|
2026-08-03 09:12:20 -07:00
|
|
|
definition Employee {
|
2026-08-03 08:48:39 -07:00
|
|
|
balance: number BEHAVES { decaying down hourly } CACHE eager
|
|
|
|
|
score: number BEHAVES { blurring adaptive confidence_95 } CACHE lazy
|
|
|
|
|
session: string BEHAVES { ttl 24h } CACHE eager
|
|
|
|
|
reputation: number BEHAVES { decaying up daily } CACHE lazy
|
|
|
|
|
clearance: string BEHAVES { blurring fixed } CACHE eager
|
|
|
|
|
lastActive: timestamp BEHAVES { decaying down hourly } CACHE lazy
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
definition Document {
|
|
|
|
|
content: string BEHAVES { blurring fixed } CACHE lazy
|
|
|
|
|
accessCount: number BEHAVES { decaying up daily } CACHE eager
|
|
|
|
|
expiresAt: timestamp BEHAVES { ttl 30d } CACHE eager
|
|
|
|
|
isPublic: boolean CACHE eager
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
fact hasBalance(user: Employee, amount: number) CACHE eager
|
|
|
|
|
fact hasScore(user: Employee, score: number) CACHE lazy
|
|
|
|
|
fact hasReputation(user: Employee, reputation: number) CACHE lazy
|
|
|
|
|
fact hasPositiveBalance(user: any) CACHE eager
|
|
|
|
|
fact hasHighScore(user: any) CACHE eager
|
|
|
|
|
fact hasGoodReputation(user: any) CACHE eager
|
|
|
|
|
fact isNotOverused(doc: any) CACHE eager
|
|
|
|
|
fact isActive(user: any) CACHE eager
|
|
|
|
|
fact recentlyActive(user: any) CACHE lazy
|
|
|
|
|
fact isPublic(doc: any) CACHE eager
|
2026-08-03 08:48:39 -07:00
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
evidence canAccessDocument(user: Employee, doc: Document) {
|
|
|
|
|
hasPositiveBalance(user)
|
2026-08-03 08:48:39 -07:00
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
hasHighScore(user)
|
2026-08-03 08:48:39 -07:00
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
hasGoodReputation(user)
|
2026-08-03 08:48:39 -07:00
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
isNotOverused(doc)
|
2026-08-03 08:48:39 -07:00
|
|
|
|
|
|
|
|
fusion majority {
|
2026-08-03 09:12:20 -07:00
|
|
|
isActive(user),
|
|
|
|
|
recentlyActive(user),
|
|
|
|
|
isPublic(doc)
|
2026-08-03 08:48:39 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
measure userEffectiveScore(user: Employee) {
|
2026-08-03 08:48:39 -07:00
|
|
|
fusion average {
|
2026-08-03 09:12:20 -07:00
|
|
|
user.score,
|
|
|
|
|
user.reputation,
|
2026-08-03 08:48:39 -07:00
|
|
|
user.balance
|
|
|
|
|
}
|
|
|
|
|
} PROVIDES number
|
|
|
|
|
|
|
|
|
|
measure documentPopularity(doc: Document) {
|
|
|
|
|
doc.accessCount
|
|
|
|
|
} PROVIDES number
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const result = compiler.compile(behaviorSystem, 'test-behaviors');
|
|
|
|
|
assert.ok(result.success, 'Complex behaviors system should compile successfully');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('Performance scenarios', () => {
|
|
|
|
|
const performanceSystem = `
|
2026-08-03 09:12:20 -07:00
|
|
|
definition Employee {
|
2026-08-03 08:48:39 -07:00
|
|
|
role: string
|
|
|
|
|
isActive: boolean
|
|
|
|
|
permissions: Permission[] CACHE eager
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
definition Resource {
|
|
|
|
|
level: string
|
2026-08-03 09:12:20 -07:00
|
|
|
owner: Employee
|
2026-08-03 08:48:39 -07:00
|
|
|
permissions: Permission[] CACHE eager
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
definition Permission {
|
|
|
|
|
name: string
|
|
|
|
|
level: string
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-03 08:48:39 -07:00
|
|
|
// High-frequency facts with limits
|
2026-08-03 09:12:20 -07:00
|
|
|
fact isMember(user: any, group: any) transitive CACHE lazy limit 5
|
|
|
|
|
fact isFriend(user: any, friend: any) symmetrical CACHE eager limit 50
|
|
|
|
|
fact hasPermission(user: Employee, resource: Resource, action: string) CACHE eager
|
|
|
|
|
fact owns(user: Employee, resource: Resource) CACHE eager
|
2026-08-03 11:34:52 -07:00
|
|
|
fact reachable(user: any, doc: any) CACHE lazy
|
2026-08-03 08:48:39 -07:00
|
|
|
|
|
|
|
|
// Optimized evidence rules
|
2026-08-03 09:12:20 -07:00
|
|
|
evidence canAccess(user: Employee, resource: Resource) {
|
2026-08-03 08:48:39 -07:00
|
|
|
owns(user, resource)
|
|
|
|
|
|
|
|
|
|
isMember(user, *group) {
|
2026-08-03 11:34:52 -07:00
|
|
|
reachable(group, resource)
|
2026-08-03 08:48:39 -07:00
|
|
|
} limit 3
|
|
|
|
|
|
|
|
|
|
WHEN hasPermission(user, resource, 'read')
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-03 09:12:20 -07:00
|
|
|
evidence canModify(user: Employee, resource: Resource) {
|
2026-08-03 08:48:39 -07:00
|
|
|
owns(user, resource)
|
|
|
|
|
|
|
|
|
|
isMember(user, *group) {
|
2026-08-03 11:34:52 -07:00
|
|
|
reachable(group, resource)
|
2026-08-03 08:48:39 -07:00
|
|
|
} limit 2
|
|
|
|
|
|
|
|
|
|
WHEN hasPermission(user, resource, 'write')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Efficient measures
|
2026-08-03 09:12:20 -07:00
|
|
|
measure userEffectivePermissions(user: Employee) {
|
2026-08-03 08:48:39 -07:00
|
|
|
user.permissions
|
2026-08-03 09:12:20 -07:00
|
|
|
} PROVIDES Permission
|
2026-08-03 08:48:39 -07:00
|
|
|
|
|
|
|
|
measure resourceAccessLevel(resource: Resource) {
|
|
|
|
|
resource.level
|
|
|
|
|
} PROVIDES string
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const result = compiler.compile(performanceSystem, 'test-performance');
|
|
|
|
|
assert.ok(result.success, 'Performance scenarios should compile successfully');
|
|
|
|
|
});
|
|
|
|
|
});
|