/**
 * Shared emitter helpers for closure gates (judge-llm, rubric, code-reviewer).
 *
 * Each gate has its own orchestration, but the steps after a gate failure are
 * the same: attribute → map severity → append to `skill-signals.json`. This
 * module centralises that pipeline so the three call sites stay thin and the
 * best-effort/never-throw behaviour is uniform.
 *
 * @module core/skill-signal-emit
 */
import * as path from 'path';
import { appendRefinementSignal } from './skill-signals/index.js';
import { attributeSkill, } from './skill-attribution.js';
/**
 * Resolve the conventional path to `.specweave/state/skill-signals.json`
 * under `projectRoot`. Matches the convention used by `SignalCollector` and
 * `suggestion-engine` so the same file is read/written across features.
 */
export function resolveSignalFilePath(projectRoot) {
    return path.join(projectRoot, '.specweave', 'state', 'skill-signals.json');
}
/**
 * Attribute + emit a single refinement signal. Best-effort: swallows all I/O
 * errors. Returns a structured result for observability/testing.
 */
export async function emitRefinementIfAttributable(input) {
    const attribution = attributeSkill(input.attribution);
    if (!attribution.skill) {
        return { emitted: false, targetSkill: null, method: attribution.method };
    }
    try {
        await appendRefinementSignal(resolveSignalFilePath(input.projectRoot), {
            source: input.source,
            targetSkill: attribution.skill,
            severity: input.severity,
            incrementId: input.incrementId,
            evidence: truncateEvidence(input.evidence),
        });
        return {
            emitted: true,
            targetSkill: attribution.skill,
            method: attribution.method,
        };
    }
    catch {
        return {
            emitted: false,
            targetSkill: attribution.skill,
            method: attribution.method,
        };
    }
}
const EVIDENCE_MAX = 500;
function truncateEvidence(text) {
    if (text.length <= EVIDENCE_MAX)
        return text;
    return text.slice(0, EVIDENCE_MAX - 1).trimEnd() + '…';
}
//# sourceMappingURL=skill-signal-emit.js.map