Files
boc/EOS/eos-integration.mjs
T
Bernt 05ed037fe8 pilot.landvex.com: HTTPS + Full Stack Verified
- DNS: pilot.landvex.com -> 16.170.83.169
- TLS: Let's Encrypt certificate (expires 2026-09-30)
- Nginx: reverse proxy with SSL termination
- API: https://pilot.landvex.com/api/v1/missions
- UI: https://pilot.landvex.com/
- Upload: POST /api/v1/missions/import (multipart/form-data)

Verified:
 https://pilot.landvex.com/health
 https://pilot.landvex.com/version
 https://pilot.landvex.com/api/v1/missions (list)
 https://pilot.landvex.com/api/v1/missions/:id (get)
 POST /api/v1/missions/import (video upload)
 UI loads with title 'LandveX Intelligence Lab'

Next: Pilot 001 — Break the system!
2026-07-02 17:34:19 +00:00

208 lines
5.2 KiB
JavaScript

#!/usr/bin/env node
// ═══════════════════════════════════════════════════════════════════════════
// EOS Integration — Gör EOS obligatoriskt i agent-flödet
// ═══════════════════════════════════════════════════════════════════════════
import { readFileSync } from 'fs';
/**
* EOS Integration säkerställer att:
* 1. Ingen agent kan hoppa över EOS-policyer
* 2. Varje förändring loggas
* 3. Blockeringar är tydliga och motiverade
* 4. Undantag kräver mänsklig granskning
*/
class EOSIntegration {
constructor() {
this.violations = [];
this.exemptions = [];
}
/**
* Kör EOS-policyer för en förändring
*/
async check(change) {
const checks = [
this.checkNoHardcodedSecrets(change),
this.checkNoDirectProd(change),
this.checkTestsRequired(change),
this.checkGitRequired(change),
this.checkNoUncommittedChanges(change),
this.checkIaCRequired(change)
];
const results = await Promise.all(checks);
const failed = results.filter(r => !r.passed);
if (failed.length > 0) {
return {
passed: false,
blocked: true,
reason: 'EOS Policy Check failed',
failures: failed,
action: 'Fix failures or request exemption'
};
}
return {
passed: true,
blocked: false,
reason: 'All checks passed',
results
};
}
async checkNoHardcodedSecrets(change) {
const secrets = this.findSecrets(change);
return {
rule: 'no-hardcoded-secrets',
passed: secrets.length === 0,
evidence: secrets.length > 0
? `Found secrets: ${secrets.join(', ')}`
: 'No secrets found',
severity: 'CRITICAL'
};
}
async checkNoDirectProd(change) {
const isProd = change.target?.includes('production');
const hasPipeline = change.pipeline !== undefined;
return {
rule: 'no-direct-prod',
passed: !isProd || hasPipeline,
evidence: isProd && !hasPipeline
? 'Production change without pipeline'
: 'OK',
severity: 'HIGH'
};
}
async checkTestsRequired(change) {
const hasTests = change.tests?.length > 0;
const isConfig = change.type === 'config';
return {
rule: 'test-required',
passed: hasTests || isConfig,
evidence: !hasTests && !isConfig
? 'No tests for code change'
: 'OK',
severity: 'MEDIUM'
};
}
async checkGitRequired(change) {
const hasGit = change.git?.commit !== undefined;
return {
rule: 'git-required',
passed: hasGit,
evidence: !hasGit
? 'No git commit'
: 'OK',
severity: 'HIGH'
};
}
async checkNoUncommittedChanges(change) {
// TODO: Kolla git status
return {
rule: 'no-uncommitted-changes',
passed: true, // TODO: Verklig kontroll
evidence: 'TODO',
severity: 'MEDIUM'
};
}
async checkIaCRequired(change) {
const isInfrastructure = change.type === 'infrastructure';
const hasTerraform = change.terraform !== undefined;
return {
rule: 'iac-required',
passed: !isInfrastructure || hasTerraform,
evidence: isInfrastructure && !hasTerraform
? 'Infrastructure change without Terraform'
: 'OK',
severity: 'HIGH'
};
}
findSecrets(change) {
const secrets = [];
const patterns = [
/password\s*=\s*["'][^"']+["']/i,
/secret\s*=\s*["'][^"']+["']/i,
/token\s*=\s*["'][^"']+["']/i,
/api_key\s*=\s*["'][^"']+["']/i,
/JWT_SECRET\s*=\s*["'][^"']+["']/i
];
for (const file of change.files || []) {
for (const pattern of patterns) {
if (pattern.test(file.content)) {
secrets.push(file.path);
break;
}
}
}
return [...new Set(secrets)];
}
/**
* Begär undantag från EOS-regel
*/
requestExemption(rule, reason, requester) {
const exemption = {
id: `exemption-${Date.now()}`,
rule,
reason,
requester,
requestedAt: new Date().toISOString(),
status: 'pending',
approvedBy: null,
approvedAt: null
};
this.exemptions.push(exemption);
return exemption;
}
/**
* Godkänn undantag
*/
approveExemption(exemptionId, approver) {
const exemption = this.exemptions.find(e => e.id === exemptionId);
if (exemption) {
exemption.status = 'approved';
exemption.approvedBy = approver;
exemption.approvedAt = new Date().toISOString();
}
return exemption;
}
}
// CLI
if (process.argv[1] === new URL(import.meta.url).pathname) {
const eos = new EOSIntegration();
// Testa med en förändring
eos.check({
id: 'test-change',
type: 'code',
files: [
{ path: 'test.mjs', content: 'const x = 1;' }
],
git: { commit: 'abc123' },
tests: ['test.mjs']
}).then(result => {
console.log(JSON.stringify(result, null, 2));
});
}
export { EOSIntegration };