/** Inputs to {@link computeShardKey}. All fields are machine-independent. */ export interface ShardKeyParts { /** Eval file path RELATIVE to the experiment directory. Never absolute. */ evalFile: string; /** Variant name. */ variant: string; /** Effective model, or `undefined` for the eval's configured default. */ model: string | undefined; /** Resolved stimulus name. */ stimulus: string; /** 0-based trial index. Callers MUST canonicalize single-trial stimuli * to `0` — the `trial-result` JSONL omits `trialIndex` for single-run * stimuli, so read it as `record.trialIndex ?? 0`. */ trialIndex: number; /** Total trials for the stimulus. Always >= 1. Used only to compute the * zero-pad width so lexicographic order agrees with numeric order. */ totalTrials: number; } /** * Compute the stable shard key for a single trial. * * The trial index is zero-padded to the width of `totalTrials - 1` so * that lexicographic comparison agrees with numeric trial order * (`trial-02` < `trial-10`). This matches the padding used by * `makeTrialItem` for the internal item id. * * @throws if `totalTrials < 1` — a zero/negative trial count would produce * a malformed, ambiguously-padded key. * @throws if `evalFile` is absolute or contains a backslash — the key must be * built from an experiment-relative, POSIX-separated path or it becomes * machine-dependent and breaks sharding/merge reconciliation. */ export declare function computeShardKey(parts: ShardKeyParts): string; /** * Assert that every shard key in `keys` is unique, throwing on the first * collision. Uniqueness is normally guaranteed by upstream validation * (unique variant names, no duplicate stimulus names within an eval, * per-variant model-collision checks), but a stable shard contract must * not *assume* it: symlinked eval roots, plugin-provided evals, or future * multi-suite experiments could collapse two distinct trials onto one * key. Sharding and merge silently mis-assign or drop work if that * happens, so we fail loudly instead. */ export declare function assertUniqueShardKeys(keys: Iterable): void; /** Per-trial contribution to a {@link computePlanDigest} input. */ export interface PlanDigestItem { /** Stable shard key (from {@link computeShardKey}). */ shardKey: string; /** Variant name. */ variant: string; /** Eval file path relative to the experiment directory. */ evalFile: string; /** Content hash of the eval file. */ evalHash: string; /** Hash of the effective resolved config (defaults + environment). */ configHash: string; } /** Run-level inputs to {@link computePlanDigest} that must match across * shards for their outputs to be mergeable. */ export interface PlanDigestMeta { /** Vally version that produced the plan. */ vallyVersion: string; /** Stimulus tag filter applied to the run, if any. */ tagFilter?: Record; /** `--variant` filter applied to the run, if any. */ variantFilter?: string; /** Per-`(eval × variant × model)` plan metadata. Required so the digest * is sensitive to eval-level divergence that produces NO work items — * plan-time validation failures, tag-filtered-to-empty evals, threshold * errors — which `items` alone cannot capture. */ evals?: ReadonlyArray; } /** Eval-level contribution to a {@link computePlanDigest} input. Captures the * planned shape of one `(eval × variant × model)` combination, including * combinations that produced no items (plan-time failures / empty filters). */ export interface PlanDigestEval { /** Eval file path relative to the experiment directory. */ evalFile: string; variant: string; model?: string; plannedStimulusCount: number; inputStimulusCount: number; plannedStimulusNames: string[]; runs: number; threshold?: number; /** Plan-time failure reason, if this combination failed to plan. */ failure?: string; } /** * Compute a digest that fingerprints the *entire planned run*: which * trials exist and the effective config behind each. Two shard processes * that planned the same experiment produce the same digest; a mismatch at * merge time is a hard error meaning "these shards did not run the same * plan" (different spec, different git SHA, different vally version, or a * different filter). * * Includes `configHash` per `(variant, evalFile)` — not just `evalHash` — * because variant-effective config (model, environment, overrides) is part * of what must agree across shards. Folds in `meta.evals` so that * combinations producing no items (plan-time failures, empty tag filters) * still influence the digest — otherwise two shards could disagree on a * validation failure yet compute identical digests. */ export declare function computePlanDigest(items: ReadonlyArray, meta: PlanDigestMeta): string; //# sourceMappingURL=shard-key.d.ts.map