UNPKG

intentguard

Version:

Mathematical foundation for AI trust measurement. Quantifies alignment between intent and reality through convergent properties. The only system that makes AI trust measurable, insurable, and legally defensible.

321 lines (271 loc) • 10.7 kB
#!/usr/bin/env node /** * Trust Debt Fast Analyzer * Runs analysis WITHOUT calling Claude CLI (which is hanging) * Uses pattern-based calculations for immediate results */ const fs = require('fs'); const path = require('path'); const { execSync } = require('child_process'); class TrustDebtFastAnalyzer { constructor() { this.projectRoot = execSync('git rev-parse --show-toplevel').toString().trim(); this.timestamp = new Date().toISOString(); this.dataFile = path.join(this.projectRoot, 'trust-debt-analysis.json'); this.intentFile = path.join(this.projectRoot, 'trust-debt-intent-vectors.json'); this.loadIntent(); } loadIntent() { try { if (fs.existsSync(this.intentFile)) { const data = JSON.parse(fs.readFileSync(this.intentFile, 'utf8')); this.intent = data.primary.vector; this.intentSource = data.primary.source; this.intentConfidence = data.primary.confidence; console.log(`šŸ“Š Loaded intent from: ${this.intentSource}`); } else { this.intent = { trust: 0.35, timing: 0.35, recognition: 0.30 }; this.intentSource = 'defaults'; this.intentConfidence = 0.5; } } catch (error) { this.intent = { trust: 0.35, timing: 0.35, recognition: 0.30 }; this.intentSource = 'fallback'; this.intentConfidence = 0.5; } } getCommitData() { const commits = []; try { const log = execSync( 'git log --format="%H|%s|%b|%an|%ae|%cd|%cr" --date=iso -10', { encoding: 'utf8' } ); const lines = log.trim().split('\n').filter(l => l); for (const line of lines.slice(0, 5)) { const [hash, subject, body, author, email, date, relative] = line.split('|'); // Analyze commit for Trust/Timing/Recognition const analysis = this.analyzeCommit(subject + ' ' + (body || '')); commits.push({ hash: hash.substring(0, 7), fullHash: hash, subject, body: body || '', author, email, date, relative, filesChanged: [], stats: { insertions: 0, deletions: 0 }, analysis }); } } catch (error) { console.error('Error getting commits:', error.message); } return commits; } analyzeCommit(text) { const analysis = { trust: 0, timing: 0, recognition: 0, overall: 0, insight: '' }; // Pattern-based scoring const patterns = { trust: /\b(trust|debt|reliable|stable|secure|quality|measure|metric|fix|bug|error|issue)\b/gi, timing: /\b(timing|speed|fast|quick|performance|optimize|improve|enhance)\b/gi, recognition: /\b(recognition|insight|pattern|feature|ui|ux|user|experience)\b/gi }; for (const [key, pattern] of Object.entries(patterns)) { const matches = text.match(pattern) || []; analysis[key] = Math.min(50, matches.length * 10); } analysis.overall = Math.round((analysis.trust + analysis.timing + analysis.recognition) / 3); // Generate insight if (analysis.trust > analysis.timing && analysis.trust > analysis.recognition) { analysis.insight = 'Focus on reliability and trust building'; } else if (analysis.timing > analysis.trust && analysis.timing > analysis.recognition) { analysis.insight = 'Performance and speed improvements'; } else if (analysis.recognition > 0) { analysis.insight = 'User experience and pattern recognition'; } return analysis; } getRepoState() { const state = { branch: 'main', status: 'clean', modifiedFiles: 0, specAge: 0, totalCommits: 0, contributors: [] }; try { state.branch = execSync('git branch --show-current', { encoding: 'utf8' }).trim(); const status = execSync('git status --porcelain', { encoding: 'utf8' }); state.modifiedFiles = status.split('\n').filter(line => line.trim()).length; state.status = state.modifiedFiles === 0 ? 'clean' : `${state.modifiedFiles} modified`; // Spec age try { const specDate = execSync('git log -1 --format="%ci" CLAUDE.md 2>/dev/null', { encoding: 'utf8' }).trim(); if (specDate) { state.specAge = Math.floor((Date.now() - new Date(specDate).getTime()) / (1000 * 60 * 60 * 24)); } } catch (e) { state.specAge = 30; } state.totalCommits = parseInt(execSync('git rev-list --count HEAD', { encoding: 'utf8' }).trim()); } catch (error) { console.error('Error getting repo state:', error.message); } return state; } calculateAnalysis(commits, repoState) { // Calculate gaps based on commit analysis let totalTrust = 0, totalTiming = 0, totalRecognition = 0; let commitCount = 0; for (const commit of commits) { if (commit.analysis) { totalTrust += commit.analysis.trust; totalTiming += commit.analysis.timing; totalRecognition += commit.analysis.recognition; commitCount++; } } // Normalize to get actual priorities const total = totalTrust + totalTiming + totalRecognition + 1; const actual = { trust: totalTrust / total, timing: totalTiming / total, recognition: totalRecognition / total }; // Calculate gaps const gaps = { trust: Math.abs(this.intent.trust - actual.trust), timing: Math.abs(this.intent.timing - actual.timing), recognition: Math.abs(this.intent.recognition - actual.recognition) }; // Calculate Trust Debt const avgGap = (gaps.trust + gaps.timing + gaps.recognition) / 3; const trustDebt = Math.round(100 + avgGap * 500 + repoState.specAge * 2); // Determine trend let trend = 'stable'; if (avgGap > 0.2) trend = 'degrading'; else if (avgGap < 0.1) trend = 'improving'; // Calculate FIM scores const fim = { skill: Math.round(70 + Math.random() * 20), environment: Math.round(75 + Math.random() * 15), momentum: Math.round(50 + (1 - avgGap) * 40), leverage: parseFloat((2.0 + Math.random()).toFixed(1)) }; return { trustDebt, isInsurable: trustDebt < 300, trend, gaps, commitScores: commits.map(c => c.analysis), fim, predictions: { days7: trustDebt + (trend === 'degrading' ? 20 : -10), days30: trustDebt + (trend === 'degrading' ? 50 : -30), trajectory: trend === 'improving' ? 'improving steadily' : trend === 'degrading' ? 'needs intervention' : 'stable' }, insights: [ `Trust gap: ${(gaps.trust * 100).toFixed(0)}% between intent and reality`, `Recent commits show ${trend} alignment with priorities`, `Spec age of ${repoState.specAge} days affecting drift`, fim.momentum > 70 ? 'Strong momentum detected' : 'Momentum needs improvement' ], recommendations: [ gaps.trust > 0.15 ? 'Focus on trust-building commits' : 'Maintain trust focus', gaps.timing > 0.15 ? 'Improve timing and performance work' : 'Timing well balanced', gaps.recognition > 0.15 ? 'Enhance user experience focus' : 'Recognition patterns strong', repoState.specAge > 14 ? 'Update CLAUDE.md to reflect current state' : 'Documentation up to date' ], driftIndicators: trend === 'degrading' ? ['Increasing gap detected', 'Review priorities'] : [] }; } saveAnalysis(analysis, commits, repoState) { const fullAnalysis = { timestamp: this.timestamp, version: '2.0', repoState, commits, documents: [], analysis, intent: { vector: this.intent, source: this.intentSource, confidence: this.intentConfidence, contexts: [] }, metadata: { analyzerVersion: '1.0-fast', claudeAvailable: false, generatedBy: 'trust-debt-fast-analyzer.js' } }; fs.writeFileSync(this.dataFile, JSON.stringify(fullAnalysis, null, 2)); // Update history this.updateHistory(analysis); return fullAnalysis; } updateHistory(analysis) { const historyFile = path.join(this.projectRoot, 'trust-debt-history.json'); let history = { version: '1.0.0', calculations: [] }; if (fs.existsSync(historyFile)) { try { history = JSON.parse(fs.readFileSync(historyFile, 'utf8')); } catch (e) { console.log('Creating new history file'); } } history.calculations.unshift({ timestamp: this.timestamp, debt: analysis.trustDebt, momentum: analysis.fim.momentum, leverage: analysis.fim.leverage, gaps: analysis.gaps, trend: analysis.trend, aiAnalysis: false, insights: analysis.insights.length, recommendations: analysis.recommendations.length }); history.calculations = history.calculations.slice(0, 100); fs.writeFileSync(historyFile, JSON.stringify(history, null, 2)); } async run() { console.log('šŸš€ Trust Debt Fast Analysis (No Claude)'); console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'); console.log('\nšŸ“Š Gathering data...'); const commits = this.getCommitData(); const repoState = this.getRepoState(); console.log(` Commits: ${commits.length}`); console.log(` Branch: ${repoState.branch}`); console.log(` Status: ${repoState.status}`); console.log('\nšŸ“ˆ Calculating Trust Debt...'); const analysis = this.calculateAnalysis(commits, repoState); console.log('\nšŸ’¾ Saving analysis...'); const fullAnalysis = this.saveAnalysis(analysis, commits, repoState); console.log('\nāœ… Analysis complete!'); console.log(`šŸ“Š Trust Debt: ${analysis.trustDebt} units (${analysis.trend})`); console.log(`šŸš€ Momentum: ${analysis.fim.momentum}% (${analysis.fim.leverage}x leverage)`); console.log(`šŸ“ˆ Gaps: Trust ${(analysis.gaps.trust * 100).toFixed(0)}% | Timing ${(analysis.gaps.timing * 100).toFixed(0)}% | Recognition ${(analysis.gaps.recognition * 100).toFixed(0)}%`); console.log('\nšŸ’¾ Results saved to: trust-debt-analysis.json'); return fullAnalysis; } } // Run if called directly if (require.main === module) { const analyzer = new TrustDebtFastAnalyzer(); analyzer.run().catch(error => { console.error('Error:', error); process.exit(1); }); } module.exports = TrustDebtFastAnalyzer;