"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PolicyResolutionError = exports.COLLABORATION_SAFETY_STOPS = exports.EVIDENCE_PROFILE_SOURCE_PRECEDENCE = exports.AGENT_MODE_SOURCE_PRECEDENCE = void 0;
exports.resolveAgentMode = resolveAgentMode;
exports.resolveEvidenceProfile = resolveEvidenceProfile;
exports.resolveIndependentTaskPolicy = resolveIndependentTaskPolicy;
exports.projectCollaborationPolicy = projectCollaborationPolicy;
exports.resolveCollaborationPolicy = resolveCollaborationPolicy;
exports.evaluateAgentModeChange = evaluateAgentModeChange;
const artifact_policy_projection_1 = require("./artifact-policy-projection");
exports.AGENT_MODE_SOURCE_PRECEDENCE = [
    "current-user-instruction",
    "session-override",
    "task",
    "parent",
    "project",
    "repository",
    "built-in"
];
exports.EVIDENCE_PROFILE_SOURCE_PRECEDENCE = [
    "task",
    "parent",
    "project",
    "repository",
    "built-in"
];
exports.COLLABORATION_SAFETY_STOPS = [
    "scope-expansion",
    "readiness-or-evidence-missing",
    "approval-required",
    "validation-failed-or-incomplete",
    "destructive-action",
    "external-system-authority",
    "disposition-or-closeout-write"
];
class PolicyResolutionError extends Error {
    field;
    source;
    constructor(field, source, value) {
        super(`Unsupported ${field} value '${value}' from '${source}'.`);
        this.name = "PolicyResolutionError";
        this.field = field;
        this.source = source;
    }
}
exports.PolicyResolutionError = PolicyResolutionError;
function resolveAgentMode(input) {
    const candidates = collectCandidates("agent_mode", [
        ["current-user-instruction", input.currentUserInstruction],
        ["session-override", input.sessionOverride],
        ["task", input.task],
        ["parent", input.parent],
        ["project", input.project],
        ["repository", input.repository]
    ], artifact_policy_projection_1.isAgentMode);
    const winner = candidates[0];
    return winner === undefined
        ? { value: "guided", source: "built-in", candidates }
        : { value: winner.value, source: winner.source, candidates };
}
function resolveEvidenceProfile(input) {
    const candidates = collectCandidates("evidence_profile", [
        ["task", input.task],
        ["parent", input.parent],
        ["project", input.project],
        ["repository", input.repository]
    ], artifact_policy_projection_1.isEvidenceProfile);
    const winner = candidates[0];
    return winner === undefined
        ? { value: "runtime", source: "built-in", candidates }
        : { value: winner.value, source: winner.source, candidates };
}
function resolveIndependentTaskPolicy(input) {
    return {
        agentMode: resolveAgentMode(input.agentMode ?? {}),
        evidenceProfile: resolveEvidenceProfile(input.evidenceProfile ?? {})
    };
}
function projectCollaborationPolicy(mode) {
    const shared = {
        mode,
        safetyStops: exports.COLLABORATION_SAFETY_STOPS,
        authorityBoundary: "collaboration-only"
    };
    if (mode === "autonomous") {
        return {
            ...shared,
            autonomy: "high",
            canProceedThroughRoutineInScopeWork: true,
            canProceedWithoutRoutineCheckIn: true,
            progressEvents: [
                "start",
                "meaningful-boundary",
                "blocker-or-deviation",
                "final-result"
            ],
            requiredCheckpoints: ["authority-scope-evidence-or-external-decision"]
        };
    }
    if (mode === "guided") {
        return {
            ...shared,
            autonomy: "medium",
            canProceedThroughRoutineInScopeWork: true,
            canProceedWithoutRoutineCheckIn: false,
            progressEvents: [
                "approach",
                "meaningful-boundary",
                "blocker-or-deviation",
                "final-result"
            ],
            requiredCheckpoints: [
                "material-design-branch",
                "structural-expansion",
                "ambiguous-tradeoff",
                "agreed-approach-change"
            ]
        };
    }
    return {
        ...shared,
        autonomy: "low",
        canProceedThroughRoutineInScopeWork: false,
        canProceedWithoutRoutineCheckIn: false,
        progressEvents: [
            "stage-proposal",
            "stage-result",
            "blocker-or-deviation",
            "final-result"
        ],
        requiredCheckpoints: [
            "initial-implementation",
            "next-material-stage",
            "significant-file-change-batch",
            "validation-or-closeout-transition",
            "meaningful-design-choice"
        ]
    };
}
function resolveCollaborationPolicy(input) {
    const resolution = resolveAgentMode(input);
    return {
        ...projectCollaborationPolicy(resolution.value),
        source: resolution.source,
        candidates: resolution.candidates
    };
}
function evaluateAgentModeChange(input) {
    const explicitUserAction = input.explicitUserAction === true;
    if (input.currentMode === input.requestedMode) {
        return {
            currentMode: input.currentMode,
            requestedMode: input.requestedMode,
            explicitUserAction,
            allowed: true,
            reason: "same-mode"
        };
    }
    const autonomyRank = {
        interactive: 0,
        guided: 1,
        autonomous: 2
    };
    if (autonomyRank[input.requestedMode] < autonomyRank[input.currentMode]) {
        return {
            currentMode: input.currentMode,
            requestedMode: input.requestedMode,
            explicitUserAction,
            allowed: true,
            reason: "autonomy-lowered"
        };
    }
    return {
        currentMode: input.currentMode,
        requestedMode: input.requestedMode,
        explicitUserAction,
        allowed: explicitUserAction,
        reason: explicitUserAction
            ? "explicit-user-autonomy-change"
            : "autonomy-raise-requires-explicit-user-action"
    };
}
function collectCandidates(field, inputs, validate) {
    const candidates = [];
    for (const [source, rawValue] of inputs) {
        if (rawValue === null || rawValue === undefined || rawValue.trim() === "")
            continue;
        const value = rawValue.trim();
        if (!validate(value))
            throw new PolicyResolutionError(field, source, value);
        candidates.push({ source, value });
    }
    return candidates;
}
