UNPKG

@claude-flow/embeddings

Version:

V3 Embedding Service - OpenAI, Transformers.js, Agentic-Flow (ONNX), Mock providers with hyperbolic embeddings, normalization, and chunking

117 lines • 5.05 kB
/** * ADR-121 Phase 22 — Ledger analyzer + regression detection. * * The witness ledger from Phase 18 stores N historical benchmark * runs as a tamper-evident hash chain. Until now it served only as * provenance — "I observed these numbers at this commit." This phase * adds the missing layer: **using the chain to detect performance * regressions** on every new run. * * Pattern: * 1. Read the ledger. * 2. For each benchmark name, pull every historical entry that * ran the same benchmark. * 3. Extract a named metric path (e.g. "results.summary.adaptive.meanRecallAt5"). * 4. Compare the current value to the baseline (most recent prior * entry, or the best, or a rolling window) and report the delta. * 5. Fail CI if the delta exceeds the configured threshold. * * Because the ledger is hash-chained (Phase 18), an attacker can't * silently rewrite a historical baseline to make a regression look * like an improvement — the chain verification would catch the * tamper before the regression check ran. */ import type { BenchmarkLedger, LedgerEntry } from './witness-ledger.js'; /** * Extract a value at a dotted path from a nested object. Returns * `undefined` if any segment is missing or the final value is not * numeric. */ export declare function getMetricAtPath(obj: unknown, path: string): number | undefined; export interface BaselineSelection { /** * Which baseline to compare against: * - 'latest' — most recent prior entry with the same benchmark name * - 'best' — the entry with the maximum (or minimum, see direction) metric value * - 'first' — the earliest entry (genesis-of-this-benchmark) */ readonly strategy: 'latest' | 'best' | 'first'; /** * Optimization direction: 'higher' means larger metric values are * better (recall, nDCG). 'lower' means smaller is better (latency, * embeds, cost). Default 'higher'. */ readonly direction?: 'higher' | 'lower'; } export interface RegressionCheckOptions { /** * Maximum allowed regression. Interpreted as a fractional change * vs baseline (e.g. 0.05 = 5%). For 'higher-is-better' metrics, a * regression means current < baseline. For 'lower-is-better' * metrics, a regression means current > baseline. * Default 0.10 (10%). */ readonly threshold?: number; /** Baseline selection — defaults to { strategy: 'latest', direction: 'higher' }. */ readonly baseline?: BaselineSelection; } export interface RegressionCheckResult { readonly benchmark: string; readonly metricPath: string; readonly currentValue: number; /** Baseline value used for the comparison, or null if no prior runs exist. */ readonly baselineValue: number | null; /** Which historical entry the baseline came from (sequence + timestamp). */ readonly baselineFrom: { sequence: number; timestamp: string; } | null; /** Absolute delta = current - baseline. */ readonly delta: number; /** * Fractional change = delta / baseline. Positive when current is * larger than baseline (regardless of optimization direction). */ readonly percentChange: number; /** True if the check passed (no major regression). */ readonly passed: boolean; /** Human-readable reason. */ readonly reason: string; } /** * Collect all ledger entries with a given benchmark name, in chain * order (oldest first). Useful for building plots, computing * rolling-window stats, etc. */ export declare function entriesForBenchmark(ledger: BenchmarkLedger, benchmarkName: string): ReadonlyArray<LedgerEntry>; /** * Pick the baseline value from a ledger for a (benchmark, metric) * pair under the supplied strategy. Returns null when the chain has * no entries with both a matching benchmark name AND a numeric value * at the metric path. */ export declare function pickBaseline(ledger: BenchmarkLedger, benchmarkName: string, metricPath: string, selection: BaselineSelection): { value: number; entry: LedgerEntry; } | null; /** * Check whether the current value regressed against the ledger * baseline. Returns a structured result with the delta and reason. */ export declare function checkRegression(ledger: BenchmarkLedger, benchmarkName: string, metricPath: string, currentValue: number, options?: RegressionCheckOptions): RegressionCheckResult; /** * Run multiple regression checks at once. Returns the per-check * results plus an aggregate `allPassed` flag. */ export interface RegressionBatchInput { readonly benchmark: string; readonly metricPath: string; readonly currentValue: number; readonly options?: RegressionCheckOptions; } export interface RegressionBatchResult { readonly allPassed: boolean; readonly checks: ReadonlyArray<RegressionCheckResult>; } export declare function checkRegressionBatch(ledger: BenchmarkLedger, inputs: ReadonlyArray<RegressionBatchInput>): RegressionBatchResult; //# sourceMappingURL=ledger-analyzer.d.ts.map