All files / lib/policy tracker_engine.ts

0% Statements 0/63
0% Branches 0/1
0% Functions 0/1
0% Lines 0/63

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79                                                                                                                                                             
/**
 * TrackerEngine
 * Reads evolutionScore from MemoryKernel (Phase 6.1)
 * Updates weights, detects trends, logs history
 */
import { LongTermMemory as MemoryKernel } from '../../lib/memory/long_term_memory';
 
import { loadRegistry, saveRegistry, upsertPolicy } from './registry';
import { appendHistory } from './history_logger';
import { decideTrend, nextStatus } from './trend_analyzer';
import { PolicyMeta, PolicyHistoryRecord } from './policy_types';
import { PolicyConfig } from '../../config/policy.config';
import { clamp, momentum, sign } from '../utils/math_utils';
 
function ensurePoliciesFromLastSnapshot(reg: PolicyMeta[]) {
  const state = MemoryKernel.getState();
  const last = state.snapshots[state.snapshots.length - 1];
  if (!last) return reg;
  for (const o of last.outcomes) {
    upsertPolicy(reg, { policyId: o.policyId });
  }
  return reg;
}
 
export function updateAllPolicies() {
  const state = MemoryKernel.getState();
  const evolutionScore = state.metrics?.evolutionScore ?? 0;
  let registry = loadRegistry();
  registry = ensurePoliciesFromLastSnapshot(registry);
 
  const updated: PolicyMeta[] = [];
 
  for (const item of registry) {
    const oldW = item.weight;
    const rawDelta = evolutionScore * PolicyConfig.learningRate;
    const prevDelta = item._lastDelta ?? 0;
    const smoothDelta = momentum(rawDelta, prevDelta);
    const newW = clamp(oldW + smoothDelta, PolicyConfig.minWeight, PolicyConfig.maxWeight);
 
    const trend = decideTrend(oldW, newW);
    const status = nextStatus(item, newW);
    const corr: -1 | 0 | 1 = (sign(newW - oldW) * sign(evolutionScore)) as -1 | 0 | 1;
 
    const updatedMeta: PolicyMeta = {
      ...item,
      weight: newW,
      trend,
      status,
      lastUpdate: new Date().toISOString(),
      _lastDelta: rawDelta,
    };
 
    if (newW !== oldW) {
      const rec: PolicyHistoryRecord = {
        policyId: item.policyId,
        oldWeight: oldW,
        newWeight: newW,
        trend,
        timestamp: updatedMeta.lastUpdate,
        reason: trendReason(trend, evolutionScore),
        correlation: corr,
      };
      appendHistory(rec);
    }
 
    updated.push(updatedMeta);
  }
 
  saveRegistry(updated);
  return { evolutionScore, updatedCount: updated.length, registry: updated };
}
 
function trendReason(trend: '↑' | '↓' | '→', evo: number) {
  if (trend === '↑') return `Weight increased due to positive evolutionScore (${evo.toFixed(4)})`;
  if (trend === '↓')
    return `Weight decreased due to negative/weak evolutionScore (${evo.toFixed(4)})`;
  return `Weight preserved (neutral vs evolutionScore ${evo.toFixed(4)})`;
}