fix: close all 5 remaining audit findings — zero legacy issues
ContextAssembler: - Accept optional MessageRepository/EvidenceStore via set_data_sources() - L6/L7/L8 query real DB data when available, fall back to descriptive text ArchitectureDesigner: - Emit architecture.impact.completed event via EventIngestor - Import eventIngestor singleton for fire-and-forget emission MainAgent: - AWAITING_CONFIRMATION now triggered for breaking/destructive requests - User confirmation required before delegating delete/break/remove tasks DoctorService: - Accept optional CapabilityRegistry in constructor - Add check_capability_deps() — verify capability tool dependencies (INV-4) TUI PermissionPrompt: - Add UiCommandChannel interface for proper INV-3 routing - Channel routes through ToolRegistry; callbacks are component-level only All 5 legacy audit findings closed. Zero stubs, zero execSync. tsc: 0 errors. E2E: 13/13 passed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -28,9 +28,11 @@ export interface DoctorReport {
|
||||
|
||||
export class DoctorService {
|
||||
private project_root: string
|
||||
private capability_registry?: any
|
||||
|
||||
constructor(project_root: string) {
|
||||
constructor(project_root: string, capability_registry?: any) {
|
||||
this.project_root = project_root
|
||||
this.capability_registry = capability_registry
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,6 +61,11 @@ export class DoctorService {
|
||||
checks.push(this.check_node())
|
||||
checks.push(this.check_project_structure())
|
||||
|
||||
// INV-4: Capability registry health — verify capability dependencies
|
||||
if (this.capability_registry) {
|
||||
checks.push(this.check_capability_deps())
|
||||
}
|
||||
|
||||
const all_passed = checks.every(c => c.passed)
|
||||
return { checks, all_passed, bootstrap_passed: true, fixable_count: checks.filter(c => c.fixable).length }
|
||||
}
|
||||
@@ -163,4 +170,45 @@ export class DoctorService {
|
||||
}
|
||||
return { name: 'project_structure', category: 'project', passed: true, message: 'Project structure valid', fixable: false }
|
||||
}
|
||||
|
||||
/**
|
||||
* INV-4: Check capability registry health — verify capability dependencies
|
||||
* are installed and accessible. Bridges CapabilityRegistry → DoctorService.
|
||||
*/
|
||||
private check_capability_deps(): DoctorCheck {
|
||||
try {
|
||||
const capabilities = this.capability_registry?.list?.() || []
|
||||
if (capabilities.length === 0) {
|
||||
return { name: 'capability_deps', category: 'capability', passed: true, message: 'No capabilities registered — nothing to check', fixable: false }
|
||||
}
|
||||
|
||||
const missing_deps: string[] = []
|
||||
for (const cap of capabilities) {
|
||||
const entry = this.capability_registry?.get?.(cap.id) || cap
|
||||
const deps = entry?.manifest?.dependencies || []
|
||||
for (const dep of deps) {
|
||||
try {
|
||||
const { execFileSync } = require('child_process')
|
||||
execFileSync('which', [dep], { stdio: 'pipe', timeout: 3000 })
|
||||
} catch {
|
||||
missing_deps.push(`${cap.name || cap.id}:${dep}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (missing_deps.length > 0) {
|
||||
return {
|
||||
name: 'capability_deps',
|
||||
category: 'capability',
|
||||
passed: false,
|
||||
message: `Missing capability dependencies: ${missing_deps.join(', ')}`,
|
||||
fixable: true,
|
||||
fix: 'Install missing tools: apt install ' + missing_deps.map(d => d.split(':')[1]).join(' ')
|
||||
}
|
||||
}
|
||||
return { name: 'capability_deps', category: 'capability', passed: true, message: `All ${capabilities.length} capabilities healthy`, fixable: false }
|
||||
} catch (e: any) {
|
||||
return { name: 'capability_deps', category: 'capability', passed: false, message: `Capability check failed: ${e.message}`, fixable: true }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user