#!/usr/bin/env node // ═══════════════════════════════════════════════════════════════════════════ // Agent Runtime — Den enda vägen genom systemet // "Ingen agent ska kunna hoppa över Planner, Project Memory eller EOS" // ═══════════════════════════════════════════════════════════════════════════ /** * Agent Runtime styr hur en agent arbetar. * * Flöde: * Task * ↓ * Planner — bryter ned arbete och planerar * ↓ * Context Builder — samlar kontext * ↓ * Project Memory — hämtar kunskap * ↓ * Knowledge Graph — förstår relationer * ↓ * EOS Policy Check — verifierar mot regler * ↓ * Developer — skriver kod * ↓ * Reviewer — granskar kod och kör EOS/SIL * ↓ * Operator — deployment, drift, rollback * ↓ * Commit * * Varje steg är obligatoriskt och loggat. */ const AGENT_ROLES = { PLANNER: { id: 'planner', name: 'Planner', description: 'Bryter ned arbete och planerar', tools: ['plan', 'estimate', 'prioritize'], permissions: ['read', 'plan'], eosChecks: ['goal-alignment', 'dependency-check'] }, DEVELOPER: { id: 'developer', name: 'Developer', description: 'Skriver kod', tools: ['read', 'write', 'edit', 'exec'], permissions: ['read', 'write', 'edit'], eosChecks: ['no-hardcoded-secrets', 'test-required', 'no-direct-prod'] }, REVIEWER: { id: 'reviewer', name: 'Reviewer', description: 'Granskar kod och kör EOS/SIL', tools: ['read', 'analyze', 'verify'], permissions: ['read', 'analyze'], eosChecks: ['all-eos-rules', 'security-scan', 'dependency-audit'] }, OPERATOR: { id: 'operator', name: 'Operator', description: 'Deployment, drift och rollback', tools: ['deploy', 'monitor', 'rollback'], permissions: ['read', 'deploy'], eosChecks: ['readiness-gate', 'release-gate', 'backup-verified'] } }; class AgentRuntime { constructor(task) { this.task = task; this.log = []; this.currentRole = null; this.context = {}; } /** * Kör en agent genom hela flödet */ async execute() { console.log(`=== Agent Runtime: ${this.task.id} ===`); // Steg 1: Planner await this.runPlanner(); // Steg 2: Context Builder await this.buildContext(); // Steg 3: Project Memory await this.queryProjectMemory(); // Steg 4: Knowledge Graph await this.queryKnowledgeGraph(); // Steg 5: EOS Policy Check const eosResult = await this.runEOSCheck(); if (!eosResult.passed) { return this.block('EOS Policy Check failed', eosResult); } // Steg 6: Developer const devResult = await this.runDeveloper(); // Steg 7: Reviewer const reviewResult = await this.runReviewer(); if (!reviewResult.passed) { return this.block('Review failed', reviewResult); } // Steg 8: Operator const opResult = await this.runOperator(); // Steg 9: Commit return this.commit(); } async runPlanner() { this.currentRole = AGENT_ROLES.PLANNER; this.logStep('PLANNER', 'Breaking down task'); // TODO: Implementera planering this.context.plan = { steps: [], estimatedTime: null, dependencies: [] }; return this.context.plan; } async buildContext() { this.logStep('CONTEXT', 'Building context'); // TODO: Samla kontext från Git, filer, etc. this.context.git = { branch: null, uncommitted: null, remote: null }; } async queryProjectMemory() { this.logStep('MEMORY', 'Querying project memory'); // TODO: Sök i MEMORY.md, dagliga filer, ADR this.context.memory = { relevantDecisions: [], similarTasks: [], lessonsLearned: [] }; } async queryKnowledgeGraph() { this.logStep('KNOWLEDGE', 'Querying knowledge graph'); // TODO: Sök i kunskapsgrafen this.context.knowledge = { relatedCapabilities: [], dependencies: [], impact: [] }; } async runEOSCheck() { this.logStep('EOS', 'Running policy checks'); // TODO: Kör alla EOS-policyer const checks = [ 'no-hardcoded-secrets', 'no-direct-prod', 'test-required', 'git-required' ]; const results = checks.map(check => ({ check, passed: true, // TODO: Verklig kontroll evidence: null })); const allPassed = results.every(r => r.passed); return { passed: allPassed, results }; } async runDeveloper() { this.currentRole = AGENT_ROLES.DEVELOPER; this.logStep('DEVELOPER', 'Implementing'); // TODO: Implementera kod this.context.implementation = { filesChanged: [], testsAdded: [], documentation: [] }; } async runReviewer() { this.currentRole = AGENT_ROLES.REVIEWER; this.logStep('REVIEWER', 'Reviewing'); // TODO: Granska kod const checks = [ 'code-quality', 'security-scan', 'eos-compliance', 'test-coverage' ]; const results = checks.map(check => ({ check, passed: true, // TODO: Verklig kontroll evidence: null })); const allPassed = results.every(r => r.passed); return { passed: allPassed, results }; } async runOperator() { this.currentRole = AGENT_ROLES.OPERATOR; this.logStep('OPERATOR', 'Preparing deployment'); // TODO: Förbered deployment this.context.deployment = { environment: null, rollbackPlan: null, healthChecks: [] }; } async commit() { this.logStep('COMMIT', 'Committing changes'); // TODO: Git commit return { status: 'success', commitHash: null, log: this.log }; } block(reason, details) { this.logStep('BLOCKED', reason); return { status: 'blocked', reason, details, log: this.log }; } logStep(phase, action) { const entry = { timestamp: new Date().toISOString(), phase, action, role: this.currentRole?.id || 'system' }; this.log.push(entry); console.log(` [${phase}] ${action}`); } } // CLI if (process.argv[1] === new URL(import.meta.url).pathname) { const runtime = new AgentRuntime({ id: 'test-task', description: 'Testa Agent Runtime' }); runtime.execute().then(result => { console.log('\n=== Resultat ==='); console.log(JSON.stringify(result, null, 2)); }); } export { AgentRuntime, AGENT_ROLES };