{"version":3,"file":"stability.d.ts","sourceRoot":"","sources":["../../../src/core/evaluation/stability.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAQhF,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,kBAAkB,EAAE,GAAG,yBAAyB,CAiC7F","sourcesContent":["import type { EvaluationArtifact, EvaluationStabilityResult } from \"./types.js\";\n\nfunction populationVariance(values: number[]): number {\n\tif (values.length < 2) return 0;\n\tconst mean = values.reduce((sum, value) => sum + value, 0) / values.length;\n\treturn values.reduce((sum, value) => sum + (value - mean) ** 2, 0) / values.length;\n}\n\nexport function aggregateStability(artifacts: EvaluationArtifact[]): EvaluationStabilityResult {\n\tconst passCount = artifacts.filter((artifact) => artifact.verdict === \"pass\").length;\n\tconst failCount = artifacts.filter((artifact) => artifact.verdict === \"fail\").length;\n\tconst invalidCount = artifacts.length - passCount - failCount;\n\tconst verdicts = new Set(artifacts.map((artifact) => artifact.verdict));\n\tconst metricIds = new Set(artifacts.flatMap((artifact) => artifact.metrics.map((metric) => metric.metricId)));\n\tconst metricVariance: Record<string, number> = {};\n\tfor (const metricId of [...metricIds].sort()) {\n\t\tconst values = artifacts\n\t\t\t.map((artifact) => artifact.metrics.find((metric) => metric.metricId === metricId)?.value)\n\t\t\t.filter((value): value is number => value !== undefined);\n\t\tif (values.length === artifacts.length) metricVariance[metricId] = populationVariance(values);\n\t}\n\tconst classification: EvaluationStabilityResult[\"classification\"] =\n\t\tartifacts.length < 2\n\t\t\t? \"insufficient_samples\"\n\t\t\t: verdicts.size > 1 || invalidCount > 0\n\t\t\t\t? \"flaky\"\n\t\t\t\t: passCount === artifacts.length\n\t\t\t\t\t? \"stable_pass\"\n\t\t\t\t\t: failCount === artifacts.length\n\t\t\t\t\t\t? \"stable_fail\"\n\t\t\t\t\t\t: \"insufficient_samples\";\n\treturn {\n\t\trepetitions: artifacts.length,\n\t\tpassCount,\n\t\tfailCount,\n\t\tinvalidCount,\n\t\toutcomeVariance: verdicts.size > 1 ? 1 : 0,\n\t\tmetricVariance,\n\t\tclassification,\n\t\tseeds: artifacts.map((artifact, index) => artifact.candidate.seed ?? index),\n\t};\n}\n"]}