#!/usr/bin/env node // ═══════════════════════════════════════════════════════════════════════════ // EOS Immutable Truth — Verifiera att det finns exakt en sanningskälla // Erik-krav: "Det finns exakt en sanningskälla för varje sak" // ═══════════════════════════════════════════════════════════════════════════ import { execSync } from 'child_process'; import { readFileSync, existsSync, writeFileSync, appendFileSync } from 'fs'; const VIOLATION_LOG = '/home/bernt/.openclaw/workspace/EOS/immutable-truth-violations.jsonl'; /** * Regler för Immutable Truth */ const TRUTH_RULES = [ { id: 'code-git', resource: 'Kod', source: 'Git', check: () => { // Kontrollera att ingen fil har ändrats utan commit try { const status = execSync('git status --short', { cwd: '/home/bernt/repos/quixzoom.com', encoding: 'utf8' }); return { valid: status.trim().length === 0, evidence: status.trim().length > 0 ? `Ocommitade ändringar:\n${status}` : 'Allt är commitat' }; } catch { return { valid: false, evidence: 'Kunde inte köra git status' }; } } }, { id: 'infra-iac', resource: 'Infrastruktur', source: 'Infrastructure as Code', check: () => { // Kontrollera att Terraform-filer finns och är commitade const hasTerraform = existsSync('/home/bernt/repos/quixzoom.com/terraform'); const hasCloudFormation = existsSync('/home/bernt/repos/quixzoom.com/cloudformation'); return { valid: hasTerraform || hasCloudFormation, evidence: hasTerraform ? 'Terraform hittat' : hasCloudFormation ? 'CloudFormation hittat' : 'Ingen IaC hittad' }; } }, { id: 'db-migrations', resource: 'Databas', source: 'Migrationer', check: () => { const hasMigrations = existsSync('/home/bernt/repos/quixzoom.com/migrations'); const hasPrisma = existsSync('/home/bernt/repos/quixzoom.com/prisma'); return { valid: hasMigrations || hasPrisma, evidence: hasMigrations ? 'Migrationer hittade' : hasPrisma ? 'Prisma schema hittat' : 'Inga migrationer hittade' }; } }, { id: 'api-openapi', resource: 'API', source: 'OpenAPI', check: () => { const hasOpenAPI = existsSync('/home/bernt/repos/quixzoom.com/openapi.yaml') || existsSync('/home/bernt/repos/quixzoom.com/openapi.json'); return { valid: hasOpenAPI, evidence: hasOpenAPI ? 'OpenAPI spec hittad' : 'Ingen OpenAPI spec hittad' }; } }, { id: 'architecture-graph', resource: 'Arkitektur', source: 'Kunskapsgraf', check: () => { const hasGraph = existsSync('/home/bernt/.openclaw/workspace/SYSTEM_GRAPH.json'); return { valid: hasGraph, evidence: hasGraph ? 'Kunskapsgraf hittad' : 'Ingen kunskapsgraf hittad' }; } } ]; class ImmutableTruthValidator { constructor() { this.rules = TRUTH_RULES; } /** * Validera alla sanningskällor */ validate() { console.log('🔍 Validerar Immutable Truth...\n'); const results = []; let violations = 0; for (const rule of this.rules) { const result = rule.check(); results.push({ id: rule.id, resource: rule.resource, source: rule.source, valid: result.valid, evidence: result.evidence }); if (!result.valid) { violations++; this.logViolation({ rule: rule.id, resource: rule.resource, expected: rule.source, evidence: result.evidence }); } const icon = result.valid ? '✅' : '❌'; console.log(`${icon} ${rule.resource} → ${rule.source}`); console.log(` ${result.evidence}`); console.log(); } const report = { timestamp: new Date().toISOString(), total: this.rules.length, valid: this.rules.length - violations, violations, results }; this.printReport(report); return report; } logViolation(violation) { appendFileSync(VIOLATION_LOG, JSON.stringify({ ...violation, timestamp: new Date().toISOString() }) + '\n', 'utf8'); } printReport(report) { console.log('╔═══════════════════════════════════════════════════════════════╗'); console.log('║ IMMUTABLE TRUTH ║'); console.log('║ Exakt en sanningskälla för varje sak ║'); console.log('╚═══════════════════════════════════════════════════════════════╝'); console.log(); console.log(`📊 RESULTAT\n`); console.log(` Regler: ${report.total}`); console.log(` Godkända: ${report.valid} ✅`); console.log(` Överträdelser: ${report.violations} ❌`); console.log(); if (report.violations > 0) { console.log('🔴 ÖVERTRÄDELSER\n'); for (const result of report.results.filter(r => !r.valid)) { console.log(` ${result.resource}: ${result.evidence}`); } console.log(); } console.log('═══════════════════════════════════════════════════════════════\n'); } } // ── Main ────────────────────────────────────────────────────────────────── const validator = new ImmutableTruthValidator(); validator.validate();