chore: recovery checkpoint - v3.0 API successfully recovered

CRITICAL CHECKPOINT - DO NOT PUSH TO GITHUB

Recovery Status:
- Successfully recovered brainy.ts from compiled JavaScript
- All core v3.0 API methods functional (add, get, update, delete, relate, find, etc.)
- Neural subsystem intact (562KB embedded patterns, NLP working)
- Augmentation pipeline operational (20+ augmentations)
- HNSW clustering system complete
- Triple Intelligence compiled (needs constructor fix)
- Test suite validates functionality

Changes preserved:
- 898 files with changes from last 3 days
- 144,475 insertions
- All augmentation improvements
- All test coverage enhancements
- Complete v3.0 feature set

This is a LOCAL checkpoint only - contains recovered work after corruption incident.
Created backup in .backups/brainy-full-20250910-151314.tar.gz

Branch: recovery-checkpoint-20250910-151433
Date: Wed Sep 10 03:18:04 PM PDT 2025
This commit is contained in:
David Snelling 2025-09-10 15:18:04 -07:00
parent f65455fb22
commit 8ff382ca3b
895 changed files with 143654 additions and 28268 deletions

View file

@ -0,0 +1,358 @@
/**
* Audit Logging Augmentation
* Provides comprehensive audit trail for all Brainy operations
*/
import { BaseAugmentation } from './brainyAugmentation.js';
import { createHash } from 'crypto';
/**
* Audit Log Augmentation
*/
export class AuditLogAugmentation extends BaseAugmentation {
constructor(config = {}) {
super(config);
this.name = 'auditLogger';
this.timing = 'around';
this.metadata = 'readonly'; // Read metadata for context
this.operations = ['all']; // Audit all operations
this.priority = 90; // Low priority, runs last
// Augmentation metadata
this.category = 'core';
this.description = 'Comprehensive audit logging for compliance and debugging';
this.logs = [];
// Merge with defaults
this.config = {
enabled: config.enabled ?? true,
logLevel: config.logLevel ?? 'standard',
includeData: config.includeData ?? false,
includeMetadata: config.includeMetadata ?? true,
retention: config.retention ?? 90, // 90 days default
storage: config.storage ?? 'memory',
filePath: config.filePath,
maxMemoryLogs: config.maxMemoryLogs ?? 10000
};
// Generate session ID
this.sessionId = this.generateId();
}
getManifest() {
return {
id: 'audit-logger',
name: 'Audit Logger',
version: '1.0.0',
description: 'Comprehensive audit trail for all operations',
longDescription: 'Records detailed audit logs of all Brainy operations for compliance, debugging, and analytics purposes.',
category: 'analytics',
configSchema: {
type: 'object',
properties: {
enabled: {
type: 'boolean',
default: true,
description: 'Enable audit logging'
},
logLevel: {
type: 'string',
enum: ['minimal', 'standard', 'detailed'],
default: 'standard',
description: 'Level of detail to log'
},
includeData: {
type: 'boolean',
default: false,
description: 'Include actual data in logs (privacy concern)'
},
includeMetadata: {
type: 'boolean',
default: true,
description: 'Include metadata in logs'
},
retention: {
type: 'number',
default: 90,
minimum: 1,
maximum: 365,
description: 'Days to retain logs'
},
storage: {
type: 'string',
enum: ['memory', 'file', 'database'],
default: 'memory',
description: 'Where to store audit logs'
},
maxMemoryLogs: {
type: 'number',
default: 10000,
description: 'Maximum logs to keep in memory'
}
}
},
configDefaults: {
enabled: true,
logLevel: 'standard',
includeData: false,
includeMetadata: true,
retention: 90,
storage: 'memory',
maxMemoryLogs: 10000
},
minBrainyVersion: '3.0.0',
keywords: ['audit', 'logging', 'compliance', 'analytics'],
documentation: 'https://docs.brainy.dev/augmentations/audit-log',
status: 'stable',
performance: {
memoryUsage: 'medium',
cpuUsage: 'low',
networkUsage: 'none'
},
features: ['operation-logging', 'configurable-detail', 'retention-management'],
enhancedOperations: ['all'],
metrics: [
{
name: 'audit_logs_created',
type: 'counter',
description: 'Total audit logs created'
},
{
name: 'audit_log_size',
type: 'gauge',
description: 'Current audit log size'
}
]
};
}
async onInitialize() {
if (!this.config.enabled) {
this.log('Audit logger disabled by configuration');
return;
}
this.log(`Audit logger initialized (level: ${this.config.logLevel}, storage: ${this.config.storage})`);
// Start retention cleanup if using memory storage
if (this.config.storage === 'memory') {
setInterval(() => {
this.cleanupOldLogs();
}, 3600000); // Every hour
}
}
async onShutdown() {
// Save any pending logs if using file storage
if (this.config.storage === 'file' && this.logs.length > 0) {
await this.flushLogs();
}
this.log('Audit logger shut down');
}
/**
* Execute augmentation - log operations
*/
async execute(operation, params, next) {
// If audit logging is disabled, just pass through
if (!this.config.enabled) {
return next();
}
const startTime = Date.now();
const logEntry = {
id: this.generateId(),
timestamp: startTime,
operation,
sessionId: this.sessionId
};
// Add params based on log level
if (this.config.logLevel !== 'minimal') {
logEntry.params = this.sanitizeParams(params);
}
try {
const result = await next();
// Log successful operation
logEntry.duration = Date.now() - startTime;
// Add result based on log level and config
if (this.config.logLevel === 'detailed' && this.config.includeData) {
logEntry.result = this.sanitizeResult(result);
}
await this.writeLog(logEntry);
return result;
}
catch (error) {
// Log failed operation
logEntry.duration = Date.now() - startTime;
logEntry.error = this.sanitizeError(error);
await this.writeLog(logEntry);
throw error;
}
}
/**
* Sanitize parameters to remove sensitive data
*/
sanitizeParams(params) {
if (!params)
return params;
// Don't include actual data unless configured
if (!this.config.includeData && params.data) {
return {
...params,
data: '[REDACTED]'
};
}
// Redact common sensitive fields
const sanitized = { ...params };
const sensitiveFields = ['password', 'token', 'apiKey', 'secret'];
for (const field of sensitiveFields) {
if (sanitized[field]) {
sanitized[field] = '[REDACTED]';
}
}
return sanitized;
}
/**
* Sanitize result data
*/
sanitizeResult(result) {
if (!result)
return result;
// For arrays, just log count
if (Array.isArray(result)) {
return { count: result.length, type: 'array' };
}
// For objects, remove sensitive fields
if (typeof result === 'object') {
const sanitized = {};
for (const key in result) {
if (!['password', 'token', 'apiKey', 'secret'].includes(key)) {
sanitized[key] = result[key];
}
}
return sanitized;
}
return result;
}
/**
* Sanitize error information
*/
sanitizeError(error) {
if (!error)
return error;
return {
message: error.message || 'Unknown error',
code: error.code,
statusCode: error.statusCode,
stack: this.config.logLevel === 'detailed' ? error.stack : undefined
};
}
/**
* Write log entry
*/
async writeLog(entry) {
switch (this.config.storage) {
case 'memory':
this.logs.push(entry);
// Enforce max memory logs
if (this.logs.length > this.config.maxMemoryLogs) {
this.logs.shift(); // Remove oldest
}
break;
case 'file':
// In production, would write to file
// For now, just add to memory
this.logs.push(entry);
break;
case 'database':
// In production, would write to database
// For now, just add to memory
this.logs.push(entry);
break;
}
}
/**
* Flush logs to persistent storage
*/
async flushLogs() {
// In production, would write to file/database
// For now, just clear old logs
if (this.logs.length > this.config.maxMemoryLogs) {
this.logs = this.logs.slice(-this.config.maxMemoryLogs);
}
}
/**
* Clean up old logs based on retention
*/
cleanupOldLogs() {
const cutoffTime = Date.now() - (this.config.retention * 24 * 60 * 60 * 1000);
this.logs = this.logs.filter(log => log.timestamp >= cutoffTime);
}
/**
* Generate unique ID
*/
generateId() {
return createHash('sha256')
.update(`${Date.now()}-${Math.random()}`)
.digest('hex')
.substring(0, 16);
}
/**
* Query audit logs
*/
queryLogs(filter) {
let results = [...this.logs];
if (filter) {
if (filter.operation) {
results = results.filter(log => log.operation === filter.operation);
}
if (filter.startTime) {
results = results.filter(log => log.timestamp >= filter.startTime);
}
if (filter.endTime) {
results = results.filter(log => log.timestamp <= filter.endTime);
}
if (filter.sessionId) {
results = results.filter(log => log.sessionId === filter.sessionId);
}
if (filter.hasError !== undefined) {
results = results.filter(log => (log.error !== undefined) === filter.hasError);
}
}
return results;
}
/**
* Get audit statistics
*/
getStats() {
const stats = {
totalLogs: this.logs.length,
operations: {},
averageDuration: 0,
errorRate: 0
};
let totalDuration = 0;
let errorCount = 0;
for (const log of this.logs) {
// Count by operation
stats.operations[log.operation] = (stats.operations[log.operation] || 0) + 1;
// Sum duration
totalDuration += log.duration;
// Count errors
if (log.error)
errorCount++;
}
if (this.logs.length > 0) {
stats.averageDuration = totalDuration / this.logs.length;
stats.errorRate = errorCount / this.logs.length;
}
return stats;
}
/**
* Export logs for analysis
*/
exportLogs() {
return [...this.logs];
}
/**
* Clear all logs
*/
clearLogs() {
this.logs = [];
}
}
/**
* Create audit log augmentation
*/
export function createAuditLogAugmentation(config) {
return new AuditLogAugmentation(config);
}
//# sourceMappingURL=auditLogAugmentation.js.map