/**
 * core/services/scoring.ts — Pure scoring functions.
 *
 * These functions operate on typed inputs and produce typed outputs
 * with zero I/O (no filesystem, network, or console access).
 *
 * Extracted from packages/eval/src/lib/calculate-scores.ts during
 * the Ports & Adapters migration (Phase 4e).
 */
import type { FeatureScore } from "../types/index.js";
import type { ActualScoreEntry, ComponentResult, TestResult, UrlMetadata } from "../types/scoring-input.js";
/**
 * Extract dimension names from a scoring profile's weight map.
 *
 * Scoring profiles (defined in config/rubrics.ts) map dimension names
 * to numeric weights. This function returns those dimension names so
 * callers can work with dynamic dimensions instead of hardcoded ones.
 */
export declare function extractDimensions(profile: Record<string, number>): string[];
/**
 * Classify a grading component into a scoring dimension.
 *
 * Prefers structured metadata (Approach 5) over heuristic string matching.
 * Returns the dimension as a kebab-case string, or null if the component
 * doesn't map to any dimension.
 *
 * Returns `string | null` so non-literacy scoring profiles (MCP, agent,
 * knowledge-probe) can define arbitrary dimension names in metadata
 * without requiring changes here.
 */
export declare function classifyRubric(component: ComponentResult): string | null;
/**
 * Detect the feature area from a test description string.
 *
 * Uses keyword matching on the lowercased description.
 */
export declare function detectFeatureArea(description: string): string;
/**
 * Extract a numeric score (0–100) from a grading component result.
 *
 * Tries (in order):
 *   1. JSON-parsed reason (grader's native 0–100 scale — most reliable)
 *   2. Direct score field (may be Promptfoo-normalized to 0–1)
 *   3. Bare number in reason text
 *
 * Promptfoo's `llm-rubric` assertion normalizes `component.score` to
 * the 0–1 range for some providers (notably GPT models, ~50% of the
 * time) while leaving others in the grader's native 0–100 range. The
 * `reason` field always contains the raw grader JSON, so we prefer it.
 *
 * When falling back to `component.score`, values in (0, 1] are rescaled
 * to 0–100 since the rubric explicitly requests a 0–100 score and a
 * true score of 0 or 1 out of 100 is vanishingly unlikely.
 */
export declare function parseRubricScore(component: ComponentResult): number;
/**
 * Extract URL metadata from a test result's JavaScript assertion output.
 *
 * Returns null if the test doesn't contain URL extraction data.
 */
export declare function extractUrlMetadata(test: TestResult): null | UrlMetadata;
/**
 * Merge baseline FeatureScore[] with agentic actual scores to produce
 * the full three-layer decomposition.
 *
 * The merge is per feature area. For each area:
 * - If baseline data exists: floor, ceiling, docLift, docQualityGap are populated
 * - If agentic data exists: actualScore is populated
 * - If both exist: retrievalGap and infrastructureEfficiency are computed
 *
 * @param baselineScores  Floor/ceiling scores from baseline evaluation (may be empty)
 * @param agenticScores   Actual scores from agentic evaluation (may be empty)
 */
export declare function mergeScores(baselineScores: FeatureScore[], agenticScores: Record<string, ActualScoreEntry>): FeatureScore[];
