/**
 * assoc() — collapses the `{ run: ctx.runId, …axisValues }` boilerplate
 * every producer would otherwise write at each `ctx.artifactWriter.emit()`
 * call site.
 *
 * Instead of:
 *   ctx.artifactWriter.emit("testOutputs", { run: ctx.runId, mode, task, model }, payload)
 *
 * Producers write:
 *   ctx.artifactWriter.emit("testOutputs", assoc(ctx, { mode, task, model }), payload)
 *
 * The `run` axis is always present because it's derivable from context;
 * every other axis is whatever the producer's local loop variables are.
 * See `docs/work-items/W0050-...json` (Q1 decision) and `tasks/plan.md § Q1`.
 */
/**
 * Build an `AssociationValues` object with `run` pinned from context and
 * the rest of the axes supplied by the caller.
 *
 * Intentionally does NOT validate that the caller supplied all axes the
 * descriptor requires — that would couple the helper to a specific type
 * and defeat the point. Invalid associations surface at `descriptor.
 * formatEntryKey()` time with a clear error, which is where the contract
 * boundary actually lives.
 */
export function assoc(ctx, partial = {}) {
    return { run: ctx.runId, ...partial };
}
const VARIANT_SUFFIX_PATTERN = /\s*\((gold|baseline)\)\s*$/i;
export function splitTaskVariant(taskId) {
    const match = VARIANT_SUFFIX_PATTERN.exec(taskId);
    if (!match)
        return { task: taskId, variant: null };
    return {
        task: taskId.slice(0, match.index).trim(),
        variant: match[1].toLowerCase(),
    };
}
/**
 * Resolve the `mode` axis value for an artifact association: prefer the
 * per-task variant when present, fall back to the high-level evaluation mode.
 * Mirrors `mode = variant ?? defaultMode` in `slim-report-summary#slimJudgments`.
 */
export function resolveVariantMode(taskId, defaultMode) {
    const { task, variant } = splitTaskVariant(taskId);
    return { mode: variant ?? defaultMode, task };
}
