All files / lib/meta apply_blueprints.ts

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

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                                                                                                                                 
/**
 * تطبيق مخطط إعادة الكتابة على سجل السياسات — مع دعم Dry-Run.
 */
import { MetaConfig } from '../../config/meta.config';
import { loadRegistry, saveRegistry } from '../policy/registry';

type PlanItem = {
  policyId: string;
  valid: boolean;
  action: 'increase_weight_gradually' | 'decrease_weight_or_monitor' | 'none';
  reason: string;
};

export function applyBlueprints(plan: PlanItem[], opts?: { dryRun?: boolean; step?: number }) {
  const dryRun = opts?.dryRun ?? MetaConfig.dryRunByDefault;
  const step = opts?.step ?? 0.05; // 5% خطوة آمنة

  const registry = loadRegistry();
  const updates: Array<{
    policyId: string;
    oldWeight: number;
    newWeight: number;
    dryRun: boolean;
    reason: string;
  }> = [];

  for (const p of plan) {
    if (!p.valid || p.action === 'none') continue;

    const idx = registry.findIndex((r) => r.policyId === p.policyId);
    if (idx === -1) continue;

    const item = registry[idx];
    const oldW = item.weight;
    let newW = oldW;

    if (p.action === 'increase_weight_gradually') {
      newW = clamp(oldW + step, 0.05, 1.0);
      item.trend = '↑';
    } else if (p.action === 'decrease_weight_or_monitor') {
      newW = clamp(oldW - step, 0.05, 1.0);
      item.trend = '↓';
    }

    item.weight = newW;
    item.lastUpdate = new Date().toISOString();

    updates.push({
      policyId: item.policyId,
      oldWeight: oldW,
      newWeight: newW,
      dryRun,
      reason: p.reason,
    });
  }

  if (!dryRun) {
    saveRegistry(registry);
  }

  return { dryRun, step, updates };
}

const clamp = (v: number, min: number, max: number) => Math.max(min, Math.min(max, v));