#!/usr/bin/env node /** * Framework Statistics Reporter * Displays comprehensive framework statistics for current session * * Triggered by "ffs" (Full Framework Stats) codeword * * Reports: * - Session context pressure and token usage * - Framework service invocation counts * - Recent audit log entries (last 10) * - Active instruction statistics * - Service health/initialization status */ const mongoose = require('mongoose'); const path = require('path'); const fs = require('fs'); // Load environment require('dotenv').config(); // Framework services const BoundaryEnforcer = require('../src/services/BoundaryEnforcer.service'); const MetacognitiveVerifier = require('../src/services/MetacognitiveVerifier.service'); const ContextPressureMonitor = require('../src/services/ContextPressureMonitor.service'); const CrossReferenceValidator = require('../src/services/CrossReferenceValidator.service'); const InstructionPersistenceClassifier = require('../src/services/InstructionPersistenceClassifier.service'); const PluralisticDeliberationOrchestrator = require('../src/services/PluralisticDeliberationOrchestrator.service'); async function getSessionStats() { const sessionStatePath = path.join(__dirname, '../.claude/session-state.json'); if (fs.existsSync(sessionStatePath)) { return JSON.parse(fs.readFileSync(sessionStatePath, 'utf8')); } return null; } async function getTokenCheckpoints() { const checkpointPath = path.join(__dirname, '../.claude/token-checkpoints.json'); if (fs.existsSync(checkpointPath)) { return JSON.parse(fs.readFileSync(checkpointPath, 'utf8')); } return null; } async function getInstructionStats() { const instructionPath = path.join(__dirname, '../.claude/instruction-history.json'); if (fs.existsSync(instructionPath)) { const history = JSON.parse(fs.readFileSync(instructionPath, 'utf8')); const active = history.instructions.filter(i => i.active); const byQuadrant = active.reduce((acc, i) => { acc[i.quadrant] = (acc[i.quadrant] || 0) + 1; return acc; }, {}); const byPersistence = active.reduce((acc, i) => { acc[i.persistence] = (acc[i.persistence] || 0) + 1; return acc; }, {}); return { total: history.instructions.length, active: active.length, inactive: history.instructions.length - active.length, byQuadrant, byPersistence, version: history.version, lastUpdated: history.last_updated }; } return null; } async function getAuditLogStats() { try { const db = require('../src/utils/db.util'); const collection = await db.getCollection('auditLogs'); // Get total count const total = await collection.countDocuments(); // Get counts by service const byService = await collection.aggregate([ { $group: { _id: '$service', count: { $sum: 1 } } }, { $sort: { count: -1 } } ]).toArray(); // Get recent entries (last 10) const recent = await collection.find() .sort({ timestamp: -1 }) .limit(10) .toArray(); // Get today's count const todayStart = new Date(); todayStart.setHours(0, 0, 0, 0); const todayCount = await collection.countDocuments({ timestamp: { $gte: todayStart } }); return { total, todayCount, byService: byService.reduce((acc, s) => { acc[s._id] = s.count; return acc; }, {}), recent: recent.map(r => ({ service: r.service, action: r.action, decision: r.decision, timestamp: r.timestamp, sessionId: r.context?.sessionId })) }; } catch (error) { console.error('Error fetching audit logs:', error.message); return null; } } async function main() { try { // Connect to MongoDB await mongoose.connect('mongodb://localhost:27017/tractatus_dev', { serverSelectionTimeoutMS: 2000 }); // Initialize framework services await BoundaryEnforcer.initialize(); await MetacognitiveVerifier.initialize(); await ContextPressureMonitor.initialize('framework-stats'); await CrossReferenceValidator.initialize(); await InstructionPersistenceClassifier.initialize(); await PluralisticDeliberationOrchestrator.initialize(); // Gather statistics const [sessionStats, tokenCheckpoints, instructionStats, auditStats] = await Promise.all([ getSessionStats(), getTokenCheckpoints(), getInstructionStats(), getAuditLogStats() ]); // Get current pressure stats const monitorStats = ContextPressureMonitor.getStats(); const pressureHistory = ContextPressureMonitor.getPressureHistory(); const latestPressure = pressureHistory && pressureHistory.length > 0 ? pressureHistory[pressureHistory.length - 1] : null; // Build report const report = { timestamp: new Date().toISOString(), session: sessionStats ? { sessionId: sessionStats.sessionId, startTime: sessionStats.startTime, messageCount: sessionStats.messageCount, status: sessionStats.status } : null, tokenUsage: tokenCheckpoints ? { budget: tokenCheckpoints.tokenBudget, checkpoints: tokenCheckpoints.checkpoints, nextCheckpoint: tokenCheckpoints.checkpoints.find(c => !c.reached) } : null, contextPressure: latestPressure ? { level: latestPressure.pressureLevel?.name || 'UNKNOWN', score: latestPressure.overallScore, timestamp: latestPressure.timestamp, metrics: latestPressure.metrics } : (monitorStats ? { level: 'UNKNOWN', score: 0, stats: monitorStats } : null), instructions: instructionStats, auditLogs: auditStats ? { total: auditStats.total, today: auditStats.todayCount, byService: auditStats.byService, recentCount: auditStats.recent.length } : null, frameworkServices: { BoundaryEnforcer: 'ACTIVE', MetacognitiveVerifier: 'ACTIVE', ContextPressureMonitor: 'ACTIVE', CrossReferenceValidator: 'ACTIVE', InstructionPersistenceClassifier: 'ACTIVE', PluralisticDeliberationOrchestrator: 'ACTIVE' } }; // Output formatted report console.log('\n╔════════════════════════════════════════════════════════════════╗'); console.log('║ TRACTATUS FRAMEWORK STATISTICS (ffs) ║'); console.log('╚════════════════════════════════════════════════════════════════╝\n'); // Session Info if (report.session) { console.log('📊 SESSION'); console.log(` Session ID: ${report.session.sessionId}`); console.log(` Start Time: ${new Date(report.session.startTime).toLocaleString()}`); console.log(` Message Count: ${report.session.messageCount}`); console.log(` Status: ${report.session.status}`); console.log(); } // Token Usage if (report.tokenUsage && report.tokenUsage.budget) { const next = report.tokenUsage.nextCheckpoint; console.log('🎯 TOKEN BUDGET'); console.log(` Total Budget: ${report.tokenUsage.budget.toLocaleString()}`); if (next) { console.log(` Next Checkpoint: ${next.threshold.toLocaleString()} (${next.percentage}%)`); } const reached = report.tokenUsage.checkpoints.filter(c => c.reached).length; console.log(` Checkpoints: ${reached}/${report.tokenUsage.checkpoints.length} reached`); console.log(); } // Context Pressure if (report.contextPressure) { console.log('⚠️ CONTEXT PRESSURE'); console.log(` Level: ${report.contextPressure.level}`); console.log(` Overall Score: ${report.contextPressure.score}%`); if (report.contextPressure.timestamp) { console.log(` Last Updated: ${new Date(report.contextPressure.timestamp).toLocaleString()}`); } if (report.contextPressure.metrics) { console.log(' Metrics:'); Object.entries(report.contextPressure.metrics).forEach(([metric, data]) => { if (data && typeof data === 'object' && 'normalized' in data) { console.log(` • ${metric}: ${(data.normalized * 100).toFixed(1)}%`); } }); } if (report.contextPressure.stats) { console.log(' Analysis Count:', report.contextPressure.stats.analysis_count); } console.log(); } // Instruction Stats if (report.instructions) { console.log('📋 INSTRUCTIONS'); console.log(` Total: ${report.instructions.total}`); console.log(` Active: ${report.instructions.active}`); console.log(` Inactive: ${report.instructions.inactive}`); console.log(` Version: ${report.instructions.version}`); console.log(' By Quadrant:'); Object.entries(report.instructions.byQuadrant).forEach(([quad, count]) => { console.log(` • ${quad}: ${count}`); }); console.log(' By Persistence:'); Object.entries(report.instructions.byPersistence).forEach(([pers, count]) => { console.log(` • ${pers}: ${count}`); }); console.log(); } // Audit Logs if (report.auditLogs) { console.log('📝 AUDIT LOGS'); console.log(` Total Decisions: ${report.auditLogs.total}`); console.log(` Today: ${report.auditLogs.today}`); console.log(' By Service:'); Object.entries(report.auditLogs.byService) .sort((a, b) => b[1] - a[1]) .forEach(([service, count]) => { console.log(` • ${service}: ${count}`); }); console.log(); } // Framework Services console.log('🔧 FRAMEWORK SERVICES'); Object.entries(report.frameworkServices).forEach(([service, status]) => { const icon = status === 'ACTIVE' ? '✓' : '✗'; console.log(` ${icon} ${service}: ${status}`); }); console.log(); console.log('╚════════════════════════════════════════════════════════════════╝\n'); // Also output JSON for programmatic access console.log('\n// JSON OUTPUT FOR PROGRAMMATIC ACCESS:'); console.log(JSON.stringify(report, null, 2)); await mongoose.disconnect(); process.exit(0); } catch (error) { console.error('Error generating framework statistics:', error); await mongoose.disconnect(); process.exit(1); } } main();