Implementing ARAL-CORE Profile
ARAL-CORE is the foundation profile covering Layers 1-5. It’s required for all ARAL agents and includes 68 normative requirements.
This guide provides a comprehensive walkthrough of implementing an ARAL-CORE conformant agent, covering all requirements across the five foundational layers.
ARAL-CORE Requirements Overview
Section titled “ARAL-CORE Requirements Overview”18 Requirements
Process management, resource limits, platform abstraction
12 Requirements
Context window, persistence, pruning strategies
15 Requirements
Action registry, validation, permissions, execution
14 Requirements
Decision engine, planning, LLM integration
9 Requirements
Identity, traits, constraints, tone enforcement
Architecture Checklist
Section titled “Architecture Checklist”Before implementing, ensure your architecture addresses:
✅ Layer 1: Runtime (18 requirements)
- RNT-001: Process lifecycle management (start, stop, restart)
- RNT-002: Resource allocation (CPU, memory, storage, network)
- RNT-003: Resource limit enforcement
- RNT-004: Platform abstraction interface
- RNT-005: Cross-platform compatibility (Linux, macOS, Windows)
- RNT-006: Error handling with retry logic
- RNT-007: Exponential backoff strategy
- RNT-008: Configurable retry limits (1-10)
- RNT-009: Health check endpoint
- RNT-010: Metrics collection (CPU, memory, uptime)
- RNT-011: Graceful shutdown (cleanup resources)
- RNT-012: Concurrent task management
- RNT-013: Task queue with priority levels
- RNT-014: Task timeout configuration
- RNT-015: Environment variable support
- RNT-016: Configuration file support (JSON/YAML)
- RNT-017: Logging with structured output
- RNT-018: Log level configuration (debug, info, warn, error)
✅ Layer 2: Memory (12 requirements)
- MEM-001: Short-term memory (STM) with context window
- MEM-002: Context window size configuration
- MEM-003: Pruning strategies (FIFO, summarize, semantic)
- MEM-004: Long-term memory (LTM) persistence
- MEM-005: Database support (SQL: PostgreSQL, MySQL, SQLite)
- MEM-006: NoSQL support (MongoDB, Redis)
- MEM-007: Data retention policies (configurable TTL)
- MEM-008: Memory search/retrieval API
- MEM-009: Semantic search support (optional)
- MEM-010: Memory encryption at rest
- MEM-011: Access control for memory operations
- MEM-012: Memory backup/restore capabilities
✅ Layer 3: Capabilities (15 requirements)
- CAP-001: Action registry system
- CAP-002: Action schema with JSON Schema
- CAP-003: Parameter validation before execution
- CAP-004: Type checking (string, number, boolean, object, array)
- CAP-005: Required vs optional parameters
- CAP-006: Default values for optional parameters
- CAP-007: Action execution engine
- CAP-008: Async action support
- CAP-009: Action timeout configuration
- CAP-010: Action error handling
- CAP-011: Permission system (RBAC)
- CAP-012: Action audit logging
- CAP-013: Built-in actions (HTTP, file, database)
- CAP-014: Custom action registration
- CAP-015: Action versioning support
✅ Layer 4: Reasoning (14 requirements)
- RSN-001: Decision engine interface
- RSN-002: LLM provider abstraction (OpenAI, Anthropic, local)
- RSN-003: Model configuration (name, temperature, max_tokens)
- RSN-004: Prompt template system
- RSN-005: System prompt injection
- RSN-006: Context injection from memory
- RSN-007: Chain-of-thought (CoT) reasoning
- RSN-008: Multi-step planning capability
- RSN-009: Planning strategy configuration (sequential, parallel)
- RSN-010: Action extraction from LLM response
- RSN-011: Function calling support (if available)
- RSN-012: Fallback strategies on LLM failure
- RSN-013: Response validation
- RSN-014: Cost tracking per LLM call
✅ Layer 5: Persona (9 requirements)
- PER-001: Persona identity (name, role, description)
- PER-002: Personality traits (0-1 scale)
- PER-003: Tone configuration (formality, emoji, language)
- PER-004: Behavioral constraints (must/must_not lists)
- PER-005: Topic constraints (allowed/forbidden)
- PER-006: System prompt template
- PER-007: Response post-processing to enforce tone
- PER-008: Constraint violation detection
- PER-009: Persona configuration via JSON/YAML
Implementation Guide
Section titled “Implementation Guide”Step 1: Runtime Implementation
Section titled “Step 1: Runtime Implementation”import { EventEmitter } from 'events';
interface RuntimeConfig { resources: { cpu: { percent: number }; memory: { mb: number }; storage: { mb: number }; }; errorHandling: { maxRetries: number; retryDelay: number; strategy: 'exponential-backoff' | 'fixed'; }; logging: { level: 'debug' | 'info' | 'warn' | 'error'; structured: boolean; };}
export class ARALCoreRuntime extends EventEmitter { private processes: Map<string, any> = new Map(); private metrics: any = {}; private config: RuntimeConfig;
constructor(config: RuntimeConfig) { super(); this.config = config; this.validateConfig(); }
// RNT-001: Process lifecycle async startProcess(id: string, fn: Function): Promise<void> { if (this.processes.has(id)) { throw new Error(`Process ${id} already running`); }
this.log('info', `Starting process: ${id}`); this.processes.set(id, { id, fn, status: 'running', startedAt: Date.now() }); this.emit('process:started', id); }
async stopProcess(id: string): Promise<void> { if (!this.processes.has(id)) { throw new Error(`Process ${id} not found`); }
this.log('info', `Stopping process: ${id}`); this.processes.delete(id); this.emit('process:stopped', id); }
async restartProcess(id: string): Promise<void> { const process = this.processes.get(id); if (!process) { throw new Error(`Process ${id} not found`); }
await this.stopProcess(id); await this.startProcess(id, process.fn); }
// RNT-003: Resource limit enforcement private enforceResourceLimits(): void { const usage = process.memoryUsage(); const memoryMB = usage.heapUsed / 1024 / 1024;
if (memoryMB > this.config.resources.memory.mb) { this.log('warn', `Memory limit exceeded: ${memoryMB.toFixed(2)}MB`); this.emit('resource:limit-exceeded', { type: 'memory', usage: memoryMB }); } }
// RNT-006: Error handling with retry async executeWithRetry<T>( fn: () => Promise<T>, retries: number = this.config.errorHandling.maxRetries ): Promise<T> { let lastError: Error;
for (let attempt = 0; attempt <= retries; attempt++) { try { return await fn(); } catch (error) { lastError = error as Error; this.log('warn', `Attempt ${attempt + 1} failed: ${error.message}`);
if (attempt < retries) { const delay = this.calculateBackoff(attempt); await this.sleep(delay); } } }
throw lastError!; }
// RNT-007: Exponential backoff private calculateBackoff(attempt: number): number { if (this.config.errorHandling.strategy === 'fixed') { return this.config.errorHandling.retryDelay; }
return Math.min( this.config.errorHandling.retryDelay * Math.pow(2, attempt), 30000 // Max 30 seconds ); }
// RNT-009: Health check healthCheck(): { status: string; uptime: number; processes: number } { return { status: 'healthy', uptime: process.uptime(), processes: this.processes.size }; }
// RNT-010: Metrics collection getMetrics(): any { const usage = process.memoryUsage(); const cpuUsage = process.cpuUsage();
return { memory: { heapUsed: usage.heapUsed / 1024 / 1024, heapTotal: usage.heapTotal / 1024 / 1024, external: usage.external / 1024 / 1024 }, cpu: { user: cpuUsage.user / 1000000, // Convert to seconds system: cpuUsage.system / 1000000 }, uptime: process.uptime(), processes: this.processes.size }; }
// RNT-011: Graceful shutdown async shutdown(): Promise<void> { this.log('info', 'Initiating graceful shutdown...');
// Stop all processes for (const [id] of this.processes) { await this.stopProcess(id); }
// Cleanup resources this.emit('shutdown'); this.log('info', 'Shutdown complete'); }
// RNT-017: Structured logging private log(level: string, message: string, meta?: any): void { if (this.config.logging.structured) { console.log(JSON.stringify({ timestamp: new Date().toISOString(), level, message, ...meta })); } else { console.log(`[${level.toUpperCase()}] ${message}`); } }
private validateConfig(): void { if (this.config.errorHandling.maxRetries < 1 || this.config.errorHandling.maxRetries > 10) { throw new Error('RNT-008: maxRetries must be between 1 and 10'); } }
private sleep(ms: number): Promise<void> { return new Promise(resolve => setTimeout(resolve, ms)); }}from typing import Dict, Callable, Anyimport asyncioimport timeimport psutilimport jsonfrom datetime import datetime
class ARALCoreRuntime: def __init__(self, config: dict): self.config = config self.processes: Dict[str, Any] = {} self.metrics = {} self._validate_config()
# RNT-001: Process lifecycle async def start_process(self, id: str, fn: Callable): if id in self.processes: raise ValueError(f"Process {id} already running")
self.log('info', f"Starting process: {id}") self.processes[id] = { 'id': id, 'fn': fn, 'status': 'running', 'started_at': time.time() }
async def stop_process(self, id: str): if id not in self.processes: raise ValueError(f"Process {id} not found")
self.log('info', f"Stopping process: {id}") del self.processes[id]
async def restart_process(self, id: str): process = self.processes.get(id) if not process: raise ValueError(f"Process {id} not found")
await self.stop_process(id) await self.start_process(id, process['fn'])
# RNT-003: Resource limit enforcement def _enforce_resource_limits(self): process = psutil.Process() memory_mb = process.memory_info().rss / 1024 / 1024
if memory_mb > self.config['resources']['memory']['mb']: self.log('warn', f"Memory limit exceeded: {memory_mb:.2f}MB")
# RNT-006: Error handling with retry async def execute_with_retry( self, fn: Callable, retries: int = None ): if retries is None: retries = self.config['error_handling']['max_retries']
last_error = None
for attempt in range(retries + 1): try: return await fn() except Exception as error: last_error = error self.log('warn', f"Attempt {attempt + 1} failed: {error}")
if attempt < retries: delay = self._calculate_backoff(attempt) await asyncio.sleep(delay / 1000)
raise last_error
# RNT-007: Exponential backoff def _calculate_backoff(self, attempt: int) -> int: if self.config['error_handling']['strategy'] == 'fixed': return self.config['error_handling']['retry_delay']
return min( self.config['error_handling']['retry_delay'] * (2 ** attempt), 30000 # Max 30 seconds )
# RNT-009: Health check def health_check(self) -> dict: return { 'status': 'healthy', 'uptime': time.time() - self.processes.get('__start__', time.time()), 'processes': len(self.processes) }
# RNT-010: Metrics collection def get_metrics(self) -> dict: process = psutil.Process()
return { 'memory': { 'rss': process.memory_info().rss / 1024 / 1024, 'vms': process.memory_info().vms / 1024 / 1024 }, 'cpu': { 'percent': process.cpu_percent() }, 'uptime': time.time() - self.processes.get('__start__', time.time()), 'processes': len(self.processes) }
# RNT-011: Graceful shutdown async def shutdown(self): self.log('info', 'Initiating graceful shutdown...')
# Stop all processes for id in list(self.processes.keys()): await self.stop_process(id)
self.log('info', 'Shutdown complete')
# RNT-017: Structured logging def log(self, level: str, message: str, meta: dict = None): if self.config['logging']['structured']: log_entry = { 'timestamp': datetime.now().isoformat(), 'level': level, 'message': message } if meta: log_entry.update(meta) print(json.dumps(log_entry)) else: print(f"[{level.upper()}] {message}")
def _validate_config(self): max_retries = self.config['error_handling']['max_retries'] if max_retries < 1 or max_retries > 10: raise ValueError('RNT-008: max_retries must be between 1 and 10')Step 2: Memory Implementation
Section titled “Step 2: Memory Implementation”interface MemoryConfig { shortTerm: { maxTokens: number; pruningStrategy: 'fifo' | 'summarize' | 'semantic'; }; longTerm: { store: 'postgresql' | 'mongodb' | 'redis'; connection: string; retentionDays: number; encryption: boolean; };}
export class ARALCoreMemory { private stm: any[] = []; private ltm: any; // Database connection private config: MemoryConfig;
constructor(config: MemoryConfig) { this.config = config; this.initializeLongTermStorage(); }
// MEM-001: Short-term memory with context window async addToShortTerm(entry: any): Promise<void> { this.stm.push({ ...entry, timestamp: Date.now() });
// MEM-002: Enforce context window size const totalTokens = this.calculateTokens(this.stm); if (totalTokens > this.config.shortTerm.maxTokens) { await this.pruneShortTerm(); } }
// MEM-003: Pruning strategies private async pruneShortTerm(): Promise<void> { switch (this.config.shortTerm.pruningStrategy) { case 'fifo': // Remove oldest entries this.stm = this.stm.slice(-10); break;
case 'summarize': // Summarize old entries const oldEntries = this.stm.slice(0, -5); const summary = await this.summarizeEntries(oldEntries); this.stm = [summary, ...this.stm.slice(-5)]; break;
case 'semantic': // Keep semantically important entries this.stm = await this.filterByRelevance(this.stm); break; } }
// MEM-004: Long-term persistence async persist(userId: string, data: any): Promise<void> { // MEM-010: Encrypt before storing const encrypted = this.config.longTerm.encryption ? this.encrypt(data) : data;
await this.ltm.insert({ user_id: userId, data: encrypted, timestamp: Date.now(), // MEM-007: Set TTL expires_at: Date.now() + (this.config.longTerm.retentionDays * 24 * 60 * 60 * 1000) });
// MEM-012: Audit log this.logAccess('write', userId); }
// MEM-008: Search/retrieval async search(userId: string, query?: string): Promise<any[]> { // MEM-011: Access control if (!this.hasAccess(userId, 'read')) { throw new Error('Access denied'); }
this.logAccess('read', userId);
if (query) { // MEM-009: Semantic search (if available) return await this.semanticSearch(userId, query); }
return await this.ltm.find({ user_id: userId }); }
private initializeLongTermStorage(): void { // MEM-005, MEM-006: Database initialization // Implementation depends on chosen store }
private calculateTokens(entries: any[]): number { // Approximate token count return entries.reduce((sum, entry) => sum + (entry.content?.length || 0) / 4, 0); }
private async summarizeEntries(entries: any[]): Promise<any> { // Use LLM to summarize return { type: 'summary', content: '...', timestamp: Date.now() }; }
private async filterByRelevance(entries: any[]): Promise<any[]> { // Use semantic similarity return entries.slice(-10); }
private encrypt(data: any): any { // Implement encryption return data; }
private hasAccess(userId: string, operation: string): boolean { // Implement RBAC return true; }
private logAccess(operation: string, userId: string): void { console.log(`[AUDIT] ${operation} by ${userId} at ${new Date().toISOString()}`); }
private async semanticSearch(userId: string, query: string): Promise<any[]> { // Implement vector search return []; }}Step 3: Capabilities Implementation
Section titled “Step 3: Capabilities Implementation”See the Capabilities Layer documentation for complete implementation details with all 15 requirements (CAP-001 through CAP-015).
Step 4: Reasoning Implementation
Section titled “Step 4: Reasoning Implementation”See the Reasoning Layer documentation for complete implementation details with all 14 requirements (RSN-001 through RSN-014).
Step 5: Persona Implementation
Section titled “Step 5: Persona Implementation”See the Persona Layer documentation for complete implementation details with all 9 requirements (PER-001 through PER-009).
Conformance Testing
Section titled “Conformance Testing”Manual Testing Checklist
Section titled “Manual Testing Checklist”Runtime Tests
// Test process lifecycleawait runtime.startProcess('test', async () => {});await runtime.stopProcess('test');await runtime.restartProcess('test');
// Test resource limitsruntime.getMetrics(); // Should show current usage
// Test error handlingawait runtime.executeWithRetry(async () => { throw new Error('Test');});
// Test health checkconst health = runtime.healthCheck();assert(health.status === 'healthy');
// Test graceful shutdownawait runtime.shutdown();Memory Tests
// Test short-term memoryawait memory.addToShortTerm({ content: 'Hello' });
// Test context window enforcementfor (let i = 0; i < 100; i++) { await memory.addToShortTerm({ content: `Message ${i}` });}// Verify pruning occurred
// Test long-term persistenceawait memory.persist('user-123', { data: 'test' });
// Test searchconst results = await memory.search('user-123', 'test');assert(results.length > 0);
// Test encryption// Verify data is encrypted in database
// Test access controltry { await memory.search('unauthorized-user', 'test'); assert(false); // Should throw} catch (error) { assert(error.message.includes('Access denied'));}Capabilities Tests
// Test action registrationcapabilities.register({ name: 'test_action', parameters: { type: 'object', properties: {} }, handler: async () => ({ success: true })});
// Test parameter validationtry { await capabilities.execute('test_action', { invalid: true }); assert(false); // Should throw validation error} catch (error) { assert(error.message.includes('validation'));}
// Test executionconst result = await capabilities.execute('test_action', {});assert(result.success === true);
// Test permissions// Verify RBAC enforcement
// Test audit logging// Check logs contain action executionsReasoning Tests
// Test LLM integrationconst response = await reasoning.reason('Hello', []);assert(response.response.length > 0);
// Test action extractionconst result = await reasoning.reason('Check order #123', []);assert(result.actions.length > 0);
// Test chain-of-thought// Verify reasoning steps are generated
// Test fallback// Simulate LLM failure and verify fallback
// Test cost trackingconst cost = reasoning.getTotalCost();assert(cost >= 0);Persona Tests
// Test persona loadingconst persona = new Persona(config);assert(persona.getName() === 'Alex');
// Test tone enforcementconst response = persona.apply('here is ur answer dude');// Verify professional tone
// Test constraint violationstry { persona.validateResponse('Political opinion...'); assert(false); // Should throw} catch (error) { assert(error.message.includes('constraint'));}
// Test trait influence// Verify personality affects responsesAutomated Conformance Testing
Section titled “Automated Conformance Testing”Use the official ARAL conformance suite:
npm install -g @aral/conformance-tester
# Run all ARAL-CORE testsaral-test --profile core --config ./agent-config.json
# Output:# ✅ RNT-001: Process lifecycle ... PASS# ✅ RNT-002: Resource allocation ... PASS# ...# ✅ PER-009: Persona configuration ... PASS## Result: 68/68 tests passed# Status: CONFORMANT ✅Certification
Section titled “Certification”Once all tests pass, apply for official ARAL-CORE certification:
- Submit test results to the ARAL Conformance Board
- Provide implementation documentation
- Pass security audit (if required)
- Receive certification badge
Use the ARAL-CORE badge in your README:
[](https://aral.dev/conformance/core)