Files
proffesor-for-testing__agen…/docs/implementation/specs/SPEC-050-A-ml-observability-persistence.md
Profa 2253d05618 feat: flatten project structure — archive v2, promote v3 to root
Remove the nested v3/ subdirectory by moving all active source code,
tests, configs, and assets directly to the project root. Archive v2/
(dead code, 847MB) to v2-archive.tar.gz.

Key changes:
- Move v3/src/ → src/, v3/tests/ → tests/, v3/packages/ → packages/
- Move v3/tsconfig.json, v3/vitest.config.ts to root
- Merge v3/package.json into root package.json (ESM, scripts, deps, exports)
- Merge v3/scripts/ into scripts/, v3/implementation/ into docs/implementation/
- Update all CI workflows to remove "cd v3 &&" and v3/ path prefixes
- Fix all init installer path resolution (3-level-up → 2-level-up)
- Fix hooks to use "node ./dist/cli/bundle.js" instead of bare "aqe"
- Update settings.json ADR/DDD directories to docs/implementation/
- Fix helper scripts (statusline, adr-compliance, ddd-tracker, guidance-hooks)
- Update 58 agent definitions: aqe/v3/ → aqe/ memory namespaces
- Update 15 guidance shards: v3/src/ → src/ path references
- Fix sync interfaces: remove v3/ and v2/ path references
- Fix test path calculations (process.cwd() + '..' no longer needed)
- Fix flaky perf test threshold (500ms → 1000ms for CI environments)
- Fix complexity-analyzer test to match ADR-051 keyword-based eligibility

Build passes, 17,901 tests pass, CLI and MCP bundles verified.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 11:35:41 +00:00

6.8 KiB

SPEC-050-A: ML Observability and Persistence

Field Value
Specification ID SPEC-050-A
Parent ADR ADR-050
Version 1.0
Status In Progress
Last Updated 2026-01-20
Author GOAP Specialist

Overview

This specification covers Actions 1-4 from the GOAP plan: ML Observability Layer, Q-Learning Persistence, SONA Pattern Persistence, and Silent Fallback Removal.


Action 1: ML Observability Layer

Priority: P0 (Critical) Estimated Time: 4 hours

Interface Definition

// File: v3/src/integrations/ruvector/observability.ts
export interface MLObservabilityMetrics {
  mlUsed: number;
  fallbackUsed: number;
  mlLatencyMs: number[];
  fallbackReasons: Map<string, number>;
}

export interface MLObservabilityReport {
  mlUsageRate: number;           // mlUsed / (mlUsed + fallbackUsed)
  avgMlLatencyMs: number;
  topFallbackReasons: Array<{ reason: string; count: number }>;
  alertTriggered: boolean;
}

export class RuVectorObservability {
  private metrics: MLObservabilityMetrics;
  private alertThreshold = 0.2; // Alert if ML usage drops below 20%

  recordMLUsage(component: string, used: boolean, latencyMs?: number): void;
  recordFallback(component: string, reason: string): void;
  checkAndAlert(): void; // Emit alert if fallback rate too high
  getReport(): MLObservabilityReport;
}

Requirements

  • RuVector wrappers exist (v3/src/integrations/ruvector/)
  • Fallback implementations exist (fallback.ts)
  • All ruvector calls emit metrics
  • usedML flag on every routing result
  • Alert system for fallback usage

Action 2: Q-Learning Persistence

Priority: P0 (Critical) Estimated Time: 8 hours

Implementation

// File: v3/src/integrations/ruvector/persistent-q-router.ts
export class PersistentQLearningRouter implements QLearningRouter {
  private store: QValueStore;
  private ewcConfig: EWCConfig;

  constructor(config: PersistentQLearningConfig) {
    this.store = createQValueStore();
    this.ewcConfig = {
      lambda: 1000.0,      // EWC regularization strength
      consolidationInterval: 3600000, // 1 hour
      fisherSampleSize: 100,
    };
  }

  async initialize(): Promise<void> {
    await this.store.initialize();
    await this.loadQValues(); // Restore from DB
  }

  async routeTask(task: TestTask): Promise<AgentRoutingResult> {
    const result = await this.mlRoute(task);
    await this.store.setQValue(agentId, stateKey, actionKey, qValue);
    return result;
  }

  private async consolidateWithEWC(): Promise<void> {
    // Apply EWC++ to prevent forgetting old patterns
  }
}

Requirements

  • QValueStore exists with SQLite backend
  • UnifiedPersistenceManager available
  • Q-Learning router exists
  • Q-values persist to memory.db
  • Q-values restored on router initialization
  • EWC++ prevents catastrophic forgetting

Action 3: SONA Pattern Persistence

Priority: P0 (Critical) Estimated Time: 6 hours

Implementation

// File: v3/src/integrations/ruvector/sona-persistence.ts
export class PersistentSONAEngine extends QESONA {
  private persistence: UnifiedPersistenceManager;

  async initialize(): Promise<void> {
    await super.initialize();
    await this.restorePatterns();
  }

  async storePattern(pattern: QESONAPattern): Promise<void> {
    super.storePattern(pattern);
    await this.persistPattern(pattern);
  }

  private async persistPattern(pattern: QESONAPattern): Promise<void> {
    const db = this.persistence.getDatabase();
    db.prepare(`
      INSERT INTO sona_patterns (id, type, domain, embedding, confidence, created_at)
      VALUES (?, ?, ?, ?, ?, datetime('now'))
    `).run(pattern.id, pattern.type, pattern.domain,
           JSON.stringify(pattern.stateEmbedding), pattern.confidence);
  }

  private async restorePatterns(): Promise<void> {
    const patterns = this.persistence.getDatabase().prepare(`
      SELECT * FROM sona_patterns ORDER BY confidence DESC LIMIT 10000
    `).all();
    for (const p of patterns) {
      super.importPatterns([this.deserializePattern(p)]);
    }
  }
}

Requirements

  • QESONA wrapper exists
  • UnifiedPersistenceManager available
  • SONA patterns persist to memory.db
  • Patterns restored on SONA initialization
  • Cross-agent pattern sharing via DB

Action 4: Remove Silent Fallbacks

Priority: P1 (High) Estimated Time: 12 hours

Modified Provider

// File: v3/src/integrations/ruvector/provider.ts (modified)
export function createQLearningRouter(config?: QLearningConfig): QLearningRouter {
  const observability = getRuVectorObservability();

  // TRY ML FIRST - no preemptive fallback
  try {
    const router = new RuVectorQLearningRouter(config);
    await router.initialize(); // Will throw if ruvector unavailable
    observability.recordMLUsage('q-learning', true);
    return router;
  } catch (error) {
    // ONLY fall back on actual error
    observability.recordFallback('q-learning', error.message);
    observability.alert({
      component: 'q-learning',
      reason: error.message,
      recommendation: 'Install/fix ruvector to enable ML routing',
    });
    return new FallbackQLearningRouter(); // Still works, but user knows
  }
}

Files to Modify

  • v3/src/integrations/ruvector/provider.ts
  • All domain coordinators that create ruvector components

Requirements

  • Fallbacks only used on explicit error
  • All fallback usage logged and alerted
  • No more silent degradation

Database Schema Additions

-- Migration: 20260120_add_sona_patterns.sql

CREATE TABLE IF NOT EXISTS sona_patterns (
  id TEXT PRIMARY KEY,
  type TEXT NOT NULL,
  domain TEXT NOT NULL,
  embedding TEXT NOT NULL,  -- JSON array
  confidence REAL DEFAULT 0.0,
  created_at TEXT DEFAULT (datetime('now')),
  updated_at TEXT DEFAULT (datetime('now'))
);

CREATE INDEX IF NOT EXISTS idx_sona_patterns_domain ON sona_patterns(domain);
CREATE INDEX IF NOT EXISTS idx_sona_patterns_confidence ON sona_patterns(confidence DESC);

Agent Assignments

Action Agent Phase
Action 1 qe-learning-coordinator Phase 1
Action 2 qe-pattern-learner Phase 1
Action 3 qe-pattern-learner Phase 2
Action 4 qe-test-architect, qe-coverage-specialist Phase 2

Changelog

Version Date Author Changes
1.0 2026-01-20 GOAP Specialist Initial specification