187 lines
6.1 KiB
JavaScript
187 lines
6.1 KiB
JavaScript
|
|
#!/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();
|