import { randomUUID } from "node:crypto";
import { z } from "zod";
import { log } from "../core/logger.js";
import { canCompleteGoalRun, decideGoalNextAction, hasFreshGoalCompletionAudit, } from "../core/goal-controller.js";
import { runGoalPrerequisiteCheckCommand } from "../core/goal-prerequisites.js";
import { appendGoalBlockers, appendGoalDecision, appendGoalEvidence, createGoalEvidence, formatGoalBlockingPrerequisiteList, formatGoalBlockingPrerequisites, getActiveGoalRun, getGoalRun, goalHasBlockingPrerequisites, loadGoalRuns, upsertGoalRun, updateGoalTask, } from "../core/goal-store.js";
import { getActiveGoalMode } from "../core/runtime-mode.js";
const PrerequisiteInput = z.object({
    id: z.string().optional().describe("Stable prerequisite id"),
    label: z.string().describe("Human-readable prerequisite label"),
    status: z.enum(["unknown", "met", "missing"]).optional(),
    check_command: z.string().optional().describe("Optional command used to check this prerequisite"),
    instructions: z.string().optional().describe("What the user must provide when missing"),
    evidence: z.string().optional().describe("Short evidence, never secret values"),
});
const HarnessInput = z.object({
    id: z.string().optional().describe("Stable harness item id"),
    label: z.string().describe("Harness/diagnostic label"),
    command: z.string().optional().describe("Command that runs this harness item"),
    path: z.string().optional().describe("File path for a harness artifact"),
    description: z.string().optional().describe("What this harness observes or verifies"),
});
const EvidencePlanInput = z.object({
    id: z.string().optional().describe("Stable evidence-plan item id"),
    label: z.string().describe("Short evidence path label"),
    mechanism: z
        .enum([
        "command",
        "test",
        "script",
        "fixture",
        "log",
        "screenshot",
        "video",
        "browser",
        "device",
        "source",
        "file",
        "manual",
    ])
        .describe("How this proof will be gathered"),
    description: z.string().describe("What this evidence proves"),
    status: z.enum(["planned", "ready", "blocked"]).optional(),
    command: z.string().optional().describe("Runnable command when available"),
    path: z.string().optional().describe("Artifact path when available"),
    instructions: z.string().optional().describe("Exact user instructions when blocked"),
    evidence: z.string().optional().describe("Observed evidence summary when ready"),
});
const GoalsParams = z.object({
    action: z
        .enum([
        "create",
        "prerequisite",
        "task",
        "evidence",
        "evidence_plan",
        "verify",
        "audit",
        "status",
        "pause",
        "resume",
        "complete",
    ])
        .describe("Goal action to perform"),
    run_id: z.string().optional().describe("Goal run id; omitted actions use the active/latest run"),
    title: z.string().optional().describe("Goal or task title"),
    goal: z.string().optional().describe("Original user objective for create"),
    success_criteria: z
        .array(z.string())
        .optional()
        .describe("Concrete criteria that must be proven before completion"),
    prerequisites: z
        .array(PrerequisiteInput)
        .optional()
        .describe("Prerequisites that must be met before launching workers"),
    prerequisite_id: z.string().optional().describe("Prerequisite id to update"),
    prerequisite_status: z
        .enum(["unknown", "met", "missing"])
        .optional()
        .describe("Updated prerequisite status"),
    prerequisite_label: z.string().optional().describe("Label for an added/updated prerequisite"),
    instructions: z.string().optional().describe("User-facing instructions for missing prerequisite"),
    harness: z.array(HarnessInput).optional().describe("Harness/diagnostic commands and files"),
    evidence_plan: z
        .array(EvidencePlanInput)
        .optional()
        .describe("Planned proof paths for end-to-end verification"),
    evidence_plan_item_id: z.string().optional().describe("Evidence-plan item id to update"),
    evidence_plan_status: z
        .enum(["planned", "ready", "blocked"])
        .optional()
        .describe("Updated evidence-plan item status"),
    verifier_command: z.string().optional().describe("Command that verifies the goal end-to-end"),
    verifier_description: z.string().optional().describe("Natural-language verifier description"),
    task_id: z.string().optional().describe("Goal task id to update"),
    task_title: z.string().optional().describe("Short worker task title"),
    task_prompt: z
        .string()
        .optional()
        .describe("Standalone prompt for a disposable Goal worker in this same project"),
    task_status: z
        .enum(["pending", "running", "verifying", "done", "failed", "blocked"])
        .optional()
        .describe("Goal task status"),
    worker_id: z.string().optional().describe("Worker id associated with a task"),
    attempts: z.number().int().min(0).optional().describe("Task attempt count"),
    summary: z.string().optional().describe("Short summary or verification note"),
    evidence_kind: z
        .enum(["log", "command", "screenshot", "file", "summary"])
        .optional()
        .describe("Evidence kind"),
    evidence_label: z.string().optional().describe("Evidence label"),
    evidence_path: z.string().optional().describe("Evidence file/log/screenshot path"),
    evidence_content: z.string().optional().describe("Short evidence content"),
    verification_status: z
        .enum(["pass", "fail", "unknown"])
        .optional()
        .describe("Verifier result status"),
    exit_code: z.number().int().optional().describe("Verifier command exit code"),
    output_path: z.string().optional().describe("Path to verifier output/log"),
    blockers: z.array(z.string()).optional().describe("Current blockers"),
});
function asPrerequisiteStatus(value) {
    if (value === "met" || value === "missing" || value === "unknown")
        return value;
    return "unknown";
}
function requiresPrerequisiteCheck(status, evidence) {
    return status === "unknown" || (status === "met" && !evidence?.trim());
}
function uncheckedPrerequisiteInstructions(label) {
    return `Check ${label} locally and record non-secret evidence before workers can start.`;
}
async function normalizePrerequisiteInput(cwd, item) {
    const requestedStatus = asPrerequisiteStatus(item.status);
    const id = item.id ?? randomUUID();
    if (item.check_command && requiresPrerequisiteCheck(requestedStatus, item.evidence)) {
        const result = await runGoalPrerequisiteCheckCommand({ cwd, command: item.check_command });
        return {
            id,
            label: item.label,
            status: result.status,
            checkCommand: item.check_command,
            evidence: result.evidence,
            ...(result.status === "missing" || item.instructions
                ? { instructions: item.instructions ?? `Make \`${item.check_command}\` pass locally.` }
                : {}),
        };
    }
    return {
        id,
        label: item.label,
        status: requestedStatus,
        ...(item.check_command ? { checkCommand: item.check_command } : {}),
        ...(item.instructions ? { instructions: item.instructions } : {}),
        ...(item.evidence ? { evidence: item.evidence } : {}),
        ...(requiresPrerequisiteCheck(requestedStatus, item.evidence) && !item.instructions
            ? { instructions: uncheckedPrerequisiteInstructions(item.label) }
            : {}),
    };
}
function asTaskStatus(value) {
    if (value === "pending" ||
        value === "running" ||
        value === "verifying" ||
        value === "done" ||
        value === "failed" ||
        value === "blocked") {
        return value;
    }
    return "pending";
}
function asEvidenceKind(value) {
    if (value === "log" ||
        value === "command" ||
        value === "screenshot" ||
        value === "file" ||
        value === "summary") {
        return value;
    }
    return "summary";
}
function asEvidencePlanStatus(value) {
    if (value === "ready" || value === "blocked" || value === "planned")
        return value;
    return "planned";
}
function asEvidenceMechanism(value) {
    if (value === "command" ||
        value === "test" ||
        value === "script" ||
        value === "fixture" ||
        value === "log" ||
        value === "screenshot" ||
        value === "video" ||
        value === "browser" ||
        value === "device" ||
        value === "source" ||
        value === "file" ||
        value === "manual") {
        return value;
    }
    return "command";
}
function asVerificationStatus(value) {
    if (value === "pass" || value === "fail" || value === "unknown")
        return value;
    return "unknown";
}
function formatRun(run) {
    const prereqs = run.prerequisites.length
        ? `${run.prerequisites.filter((item) => item.status === "met").length}/${run.prerequisites.length} prereqs met`
        : "no prereqs";
    const tasks = run.tasks.length
        ? `${run.tasks.filter((item) => item.status === "done").length}/${run.tasks.length} tasks done`
        : "no tasks";
    const verifier = run.verifier?.lastResult
        ? `verifier ${run.verifier.lastResult.status}`
        : run.verifier?.command
            ? "verifier configured"
            : "no verifier";
    const audit = run.completionAudit
        ? `, final audit ${run.completionAudit.status}`
        : run.verifier?.lastResult?.status === "pass"
            ? ", final audit missing"
            : "";
    const blocker = goalHasBlockingPrerequisites(run)
        ? `\nUser prerequisites: ${formatGoalBlockingPrerequisites(run)}`
        : "";
    return `[${run.status}] ${run.title} (id: ${run.id.slice(0, 8)}) — ${prereqs}, ${tasks}, ${verifier}${audit}${blocker}`;
}
function recoverableTaskStatus(status) {
    return status === "pending" || status === "failed";
}
function statusAfterTaskPatch(run, status) {
    if ((run.status !== "failed" && run.status !== "passed") || !recoverableTaskStatus(status)) {
        return run.status;
    }
    return goalHasBlockingPrerequisites(run) ? "blocked" : "ready";
}
function setupBlockersForRun(run) {
    const blockers = [];
    if (run.successCriteria.length === 0)
        blockers.push("Goal setup incomplete: success criteria are required.");
    if (run.evidencePlan.length === 0)
        blockers.push("Goal setup incomplete: evidence_plan is required.");
    if (!run.verifier?.command)
        blockers.push("Goal setup incomplete: verifier_command is required.");
    return blockers;
}
function validatePassAuditContract(run, summary, outputPath) {
    const verifier = run.verifier?.lastResult;
    if (!verifier)
        return "cannot audit completion before a verifier result exists.";
    if (!summary.startsWith("FINAL_AUDIT_PASS"))
        return "pass audit summary must start with FINAL_AUDIT_PASS.";
    if (!summary.includes(`verifier_checked_at=${verifier.checkedAt}`)) {
        return `pass audit summary must include verifier_checked_at=${verifier.checkedAt}.`;
    }
    if (!outputPath && !summary.match(/(?:output|artifact|log|path)=\S+/)) {
        return "pass audit must include output_path or an output/artifact/log/path reference in the summary.";
    }
    return undefined;
}
async function resolveRun(cwd, id) {
    if (id)
        return getGoalRun(cwd, id);
    return getActiveGoalRun(cwd);
}
export function createGoalsTool(cwd, goalModeRef) {
    return {
        name: "goals",
        description: "Manage durable Goal runs for /goal and Ctrl+G workflows. Use this instead of tasks when the user wants a programmatic goal loop: define success criteria first, check prerequisites before launching workers, persist harness/diagnostics/evidence, add standalone worker tasks, record final completion audits, and only mark the goal complete when verifier plus final-audit evidence proves the original objective. Do not require paid services or signups without recording a blocker and asking the user for the missing prerequisite.",
        parameters: GoalsParams,
        executionMode: "sequential",
        async execute(args) {
            if (getActiveGoalMode(goalModeRef) === "planner") {
                return "Error: goals is restricted in Goal planner mode. Emit a compact GOAL_PLAN block only; setup creates durable Goal state.";
            }
            switch (args.action) {
                case "create": {
                    if (!args.title)
                        return "Error: title is required for create.";
                    if (!args.goal)
                        return "Error: goal is required for create.";
                    const existing = args.run_id ? await getGoalRun(cwd, args.run_id) : null;
                    const prerequisites = args.prerequisites
                        ? await Promise.all(args.prerequisites.map((item) => normalizePrerequisiteInput(cwd, item)))
                        : undefined;
                    const harness = args.harness?.map((item) => ({
                        id: item.id ?? randomUUID(),
                        label: item.label,
                        ...(item.command ? { command: item.command } : {}),
                        ...(item.path ? { path: item.path } : {}),
                        ...(item.description ? { description: item.description } : {}),
                    }));
                    const evidencePlan = args.evidence_plan?.map((item) => ({
                        id: item.id ?? randomUUID(),
                        label: item.label,
                        mechanism: asEvidenceMechanism(item.mechanism),
                        description: item.description,
                        status: item.status ?? "planned",
                        ...(item.command ? { command: item.command } : {}),
                        ...(item.path ? { path: item.path } : {}),
                        ...(item.instructions ? { instructions: item.instructions } : {}),
                        ...(item.evidence ? { evidence: item.evidence } : {}),
                    }));
                    const verifier = args.verifier_command || args.verifier_description
                        ? {
                            description: args.verifier_description ?? existing?.verifier?.description ?? "Goal verifier",
                            ...((args.verifier_command ?? existing?.verifier?.command)
                                ? { command: args.verifier_command ?? existing?.verifier?.command }
                                : {}),
                            ...(existing?.verifier?.lastResult
                                ? { lastResult: existing.verifier.lastResult }
                                : {}),
                        }
                        : existing?.verifier;
                    const nextPrerequisites = prerequisites ?? existing?.prerequisites ?? [];
                    const missingPrerequisites = formatGoalBlockingPrerequisiteList(nextPrerequisites);
                    const hasBlockingPrerequisites = missingPrerequisites !== "Goal has no missing user prerequisites.";
                    const draftProbe = {
                        successCriteria: args.success_criteria ?? existing?.successCriteria ?? [],
                        evidencePlan: evidencePlan ?? existing?.evidencePlan ?? [],
                        verifier,
                    };
                    const setupBlockers = setupBlockersForRun(draftProbe);
                    const blockers = Array.from(new Set([
                        ...(args.blockers ?? existing?.blockers ?? []),
                        ...(hasBlockingPrerequisites ? [missingPrerequisites] : []),
                        ...setupBlockers,
                    ]));
                    const run = await upsertGoalRun(cwd, {
                        ...(args.run_id ? { id: args.run_id } : {}),
                        title: args.title,
                        goal: args.goal,
                        status: setupBlockers.length > 0
                            ? "draft"
                            : hasBlockingPrerequisites
                                ? "blocked"
                                : (existing?.status ?? "ready"),
                        successCriteria: draftProbe.successCriteria,
                        prerequisites: nextPrerequisites,
                        harness: harness ?? existing?.harness ?? [],
                        evidencePlan: draftProbe.evidencePlan,
                        ...(verifier ? { verifier } : {}),
                        blockers,
                    });
                    await appendGoalDecision(cwd, run.id, {
                        kind: args.run_id ? "update" : "create",
                        reason: `criteria=${run.successCriteria.length}; prerequisites=${run.prerequisites.length}; harness=${run.harness.length}; evidence_plan=${run.evidencePlan.length}; verifier=${run.verifier?.command ? "configured" : "missing"}`,
                    });
                    log("INFO", "goals", `Goal created: ${run.title}`, { id: run.id, status: run.status });
                    return goalHasBlockingPrerequisites(run)
                        ? `Goal ${args.run_id ? "updated" : "created"}: "${run.title}" (id: ${run.id.slice(0, 8)}, ${run.status}). User prerequisites: ${formatGoalBlockingPrerequisites(run)}`
                        : `Goal ${args.run_id ? "updated" : "created"}: "${run.title}" (id: ${run.id.slice(0, 8)}, ${run.status})`;
                }
                case "status": {
                    if (args.run_id) {
                        const run = await getGoalRun(cwd, args.run_id);
                        return run ? formatRun(run) : `Error: no goal found matching id "${args.run_id}".`;
                    }
                    const runs = await loadGoalRuns(cwd);
                    if (runs.length === 0)
                        return "No goals.";
                    return runs.map(formatRun).join("\n");
                }
                case "prerequisite": {
                    const run = await resolveRun(cwd, args.run_id);
                    if (!run)
                        return "Error: no active goal run found.";
                    const prereqId = args.prerequisite_id;
                    if (!prereqId && !args.prerequisite_label) {
                        return "Error: prerequisite_id or prerequisite_label is required.";
                    }
                    const prerequisites = [...run.prerequisites];
                    const index = prereqId
                        ? prerequisites.findIndex((item) => item.id === prereqId || item.id.startsWith(prereqId))
                        : -1;
                    const existingPrerequisite = index >= 0 ? prerequisites[index] : undefined;
                    const patch = {
                        id: prereqId ?? randomUUID(),
                        label: args.prerequisite_label ?? existingPrerequisite?.label ?? prereqId ?? "Prerequisite",
                        status: asPrerequisiteStatus(args.prerequisite_status),
                        ...(args.instructions ? { instructions: args.instructions } : {}),
                        ...(args.summary ? { evidence: args.summary } : {}),
                        ...(asPrerequisiteStatus(args.prerequisite_status) === "met" && !args.summary
                            ? {
                                instructions: args.instructions ??
                                    uncheckedPrerequisiteInstructions(args.prerequisite_label ??
                                        existingPrerequisite?.label ??
                                        prereqId ??
                                        "Prerequisite"),
                            }
                            : {}),
                    };
                    if (index >= 0) {
                        prerequisites[index] = {
                            ...prerequisites[index],
                            ...patch,
                            id: prerequisites[index].id,
                        };
                    }
                    else {
                        prerequisites.push(patch);
                    }
                    const stillBlocked = goalHasBlockingPrerequisites({ ...run, prerequisites });
                    const updated = await upsertGoalRun(cwd, {
                        ...run,
                        prerequisites,
                        status: stillBlocked ? "blocked" : "ready",
                        blockers: stillBlocked ? run.blockers : [],
                    });
                    await appendGoalDecision(cwd, updated.id, {
                        kind: "prerequisites",
                        reason: `Prerequisite ${patch.label} is ${patch.status}; run is ${updated.status}.`,
                    });
                    return goalHasBlockingPrerequisites(updated)
                        ? `Prerequisite updated for "${updated.title}" (${updated.status}). User prerequisites: ${formatGoalBlockingPrerequisites(updated)}`
                        : `User prerequisites complete for "${updated.title}". Goal is ready to run.`;
                }
                case "task": {
                    const run = await resolveRun(cwd, args.run_id);
                    if (!run)
                        return "Error: no active goal run found.";
                    if (!args.task_id && (!args.task_title || !args.task_prompt)) {
                        return "Error: task_title and task_prompt are required when adding a task.";
                    }
                    const taskId = args.task_id ?? randomUUID();
                    const existingTask = run.tasks.find((task) => task.id === taskId || task.id.startsWith(taskId));
                    const taskExisted = existingTask !== undefined;
                    if (!taskExisted && (!args.task_title || !args.task_prompt)) {
                        return "Error: task_title and task_prompt are required when adding a task.";
                    }
                    const taskStatus = asTaskStatus(args.task_status);
                    const updated = await updateGoalTask(cwd, run.id, taskId, {
                        id: taskId,
                        ...(args.task_title ? { title: args.task_title } : {}),
                        ...(args.task_prompt ? { prompt: args.task_prompt } : {}),
                        status: taskStatus,
                        ...(args.worker_id ? { workerId: args.worker_id } : {}),
                        ...(args.attempts !== undefined ? { attempts: args.attempts } : {}),
                        ...(args.summary ? { lastSummary: args.summary } : {}),
                    });
                    const recovered = updated
                        ? await upsertGoalRun(updated.projectPath, {
                            ...updated,
                            status: statusAfterTaskPatch(updated, taskStatus),
                        })
                        : null;
                    if (!recovered)
                        return `Error: no task found matching id "${taskId}".`;
                    const updatedTask = recovered.tasks.find((task) => task.id === existingTask?.id || task.id === taskId || task.id.startsWith(taskId));
                    return `Goal task ${taskExisted ? "updated" : "added"}: "${updatedTask?.title ?? args.task_title ?? taskId}".`;
                }
                case "evidence": {
                    const run = await resolveRun(cwd, args.run_id);
                    if (!run)
                        return "Error: no active goal run found.";
                    if (!args.evidence_label && !args.summary)
                        return "Error: evidence_label or summary is required.";
                    const updated = await appendGoalEvidence(cwd, run.id, {
                        kind: asEvidenceKind(args.evidence_kind),
                        label: args.evidence_label ?? "Evidence",
                        ...(args.evidence_path ? { path: args.evidence_path } : {}),
                        ...(args.evidence_content || args.summary
                            ? { content: args.evidence_content ?? args.summary }
                            : {}),
                    });
                    if (!updated)
                        return "Error: failed to append evidence.";
                    return `Evidence added to "${updated.title}".`;
                }
                case "evidence_plan": {
                    const run = await resolveRun(cwd, args.run_id);
                    if (!run)
                        return "Error: no active goal run found.";
                    const evidencePlanItemId = args.evidence_plan_item_id;
                    if (!evidencePlanItemId)
                        return "Error: evidence_plan_item_id is required.";
                    const evidencePlan = [...run.evidencePlan];
                    const index = evidencePlan.findIndex((item) => item.id === evidencePlanItemId || item.id.startsWith(evidencePlanItemId));
                    if (index < 0) {
                        return `Error: no evidence-plan item found matching id "${args.evidence_plan_item_id}".`;
                    }
                    const existing = evidencePlan[index];
                    const status = asEvidencePlanStatus(args.evidence_plan_status);
                    evidencePlan[index] = {
                        ...existing,
                        status,
                        ...(args.instructions ? { instructions: args.instructions } : {}),
                        ...(args.evidence_content || args.summary
                            ? { evidence: args.evidence_content ?? args.summary }
                            : {}),
                        ...(args.evidence_path ? { path: args.evidence_path } : {}),
                    };
                    const canRecoverBlockedRun = run.status === "blocked" && status === "ready" && !goalHasBlockingPrerequisites(run);
                    const updated = await upsertGoalRun(cwd, {
                        ...run,
                        evidencePlan,
                        status: canRecoverBlockedRun ? "ready" : run.status,
                        blockers: canRecoverBlockedRun ? [] : run.blockers,
                    });
                    await appendGoalDecision(cwd, updated.id, {
                        kind: "evidence_plan",
                        reason: `Evidence-plan item ${existing.label} is ${status}.`,
                    });
                    return `Evidence-plan item updated for "${updated.title}": "${existing.label}" is ${status}.`;
                }
                case "verify": {
                    const run = await resolveRun(cwd, args.run_id);
                    if (!run)
                        return "Error: no active goal run found.";
                    const result = {
                        status: asVerificationStatus(args.verification_status),
                        summary: args.summary ?? "Verifier recorded.",
                        ...((args.verifier_command ?? run.verifier?.command)
                            ? { command: args.verifier_command ?? run.verifier?.command }
                            : {}),
                        ...(args.exit_code !== undefined ? { exitCode: args.exit_code } : {}),
                        ...(args.output_path ? { outputPath: args.output_path } : {}),
                        checkedAt: new Date().toISOString(),
                    };
                    const runWithVerifier = {
                        ...run,
                        verifier: {
                            description: args.verifier_description ?? run.verifier?.description ?? "Goal verifier",
                            ...((args.verifier_command ?? run.verifier?.command)
                                ? { command: args.verifier_command ?? run.verifier?.command }
                                : {}),
                            lastResult: result,
                        },
                        ...(result.status === "pass"
                            ? {
                                completionAudit: {
                                    status: "unknown",
                                    summary: "Final completion audit pending for latest verifier result.",
                                    checkedAt: result.checkedAt,
                                    verifierCheckedAt: result.checkedAt,
                                    ...(result.outputPath ? { outputPath: result.outputPath } : {}),
                                },
                            }
                            : {}),
                        evidence: [
                            ...run.evidence,
                            createGoalEvidence({
                                kind: "command",
                                label: "Verifier result",
                                content: result.summary,
                                ...(result.outputPath ? { path: result.outputPath } : {}),
                            }),
                        ],
                    };
                    const completion = canCompleteGoalRun(runWithVerifier);
                    const updated = await upsertGoalRun(cwd, {
                        ...runWithVerifier,
                        status: result.status === "pass" && completion.ok
                            ? "passed"
                            : result.status === "pass"
                                ? goalHasBlockingPrerequisites(runWithVerifier)
                                    ? "blocked"
                                    : "ready"
                                : result.status === "fail"
                                    ? goalHasBlockingPrerequisites(runWithVerifier)
                                        ? "blocked"
                                        : "ready"
                                    : "verifying",
                        blockers: result.status === "pass" ? [] : run.blockers,
                        activeWorkerId: undefined,
                    });
                    return `Verifier recorded for "${updated.title}": ${result.status}.`;
                }
                case "audit": {
                    const run = await resolveRun(cwd, args.run_id);
                    if (!run)
                        return "Error: no active goal run found.";
                    const verifierResult = run.verifier?.lastResult;
                    if (!verifierResult || verifierResult.status !== "pass") {
                        return "Error: cannot audit completion before a passing verifier result exists.";
                    }
                    const auditStatus = asVerificationStatus(args.verification_status);
                    const auditSummary = args.summary ?? "Final completion audit recorded.";
                    const auditOutputPath = args.output_path ?? verifierResult.outputPath;
                    if (auditStatus === "pass") {
                        const contractError = validatePassAuditContract(run, auditSummary, auditOutputPath);
                        if (contractError)
                            return `Error: invalid final completion audit pass contract: ${contractError}`;
                    }
                    const completionAudit = {
                        status: auditStatus,
                        summary: auditSummary,
                        checkedAt: new Date().toISOString(),
                        verifierCheckedAt: verifierResult.checkedAt,
                        ...(auditOutputPath ? { outputPath: auditOutputPath } : {}),
                    };
                    const runWithAudit = {
                        ...run,
                        completionAudit,
                        evidence: [
                            ...run.evidence,
                            createGoalEvidence({
                                kind: "summary",
                                label: `Final completion audit ${completionAudit.status}`,
                                content: completionAudit.summary,
                                ...(completionAudit.outputPath ? { path: completionAudit.outputPath } : {}),
                            }),
                        ],
                    };
                    const auditCheck = hasFreshGoalCompletionAudit(runWithAudit);
                    const completion = canCompleteGoalRun(runWithAudit);
                    const updated = await upsertGoalRun(cwd, {
                        ...runWithAudit,
                        status: completionAudit.status === "pass" && auditCheck.ok && completion.ok
                            ? "passed"
                            : goalHasBlockingPrerequisites(runWithAudit)
                                ? "blocked"
                                : "ready",
                        blockers: completionAudit.status === "pass" && auditCheck.ok ? [] : run.blockers,
                        activeWorkerId: undefined,
                    });
                    await appendGoalDecision(cwd, updated.id, {
                        kind: "completion_audit",
                        reason: auditCheck.reason,
                        content: `status=${completionAudit.status}; verifierCheckedAt=${completionAudit.verifierCheckedAt ?? ""}; outputPath=${completionAudit.outputPath ?? ""}`,
                    });
                    return `Completion audit recorded for "${updated.title}": ${completionAudit.status}.`;
                }
                case "pause":
                case "resume":
                case "complete": {
                    const run = await resolveRun(cwd, args.run_id);
                    if (!run)
                        return "Error: no active goal run found.";
                    let status;
                    if (args.action === "pause") {
                        if (run.activeWorkerId || run.tasks.some((task) => task.status === "running")) {
                            return `Error: cannot pause goal while worker ${run.activeWorkerId ?? "task"} is active. Stop the worker first or wait for it to finish.`;
                        }
                        status = "paused";
                    }
                    else if (args.action === "resume") {
                        const missing = goalHasBlockingPrerequisites(run)
                            ? formatGoalBlockingPrerequisites(run)
                            : "";
                        if (missing) {
                            const updated = await upsertGoalRun(cwd, {
                                ...run,
                                status: "blocked",
                                blockers: appendGoalBlockers(run.blockers, missing),
                                evidence: [
                                    ...run.evidence,
                                    createGoalEvidence({
                                        kind: "summary",
                                        label: "Goal resume blocked",
                                        content: missing,
                                    }),
                                ],
                            });
                            return `Goal "${updated.title}" resume blocked: ${missing}`;
                        }
                        const requestedAt = new Date().toISOString();
                        const resumed = {
                            ...run,
                            status: run.status === "running" || run.status === "verifying" ? run.status : "ready",
                            continueRequestedAt: requestedAt,
                            evidence: [
                                ...run.evidence,
                                createGoalEvidence({
                                    kind: "summary",
                                    label: "Goal resume requested",
                                    content: "Continuation requested; the next eligible Goal action will run automatically when no worker/verifier is active.",
                                    createdAt: requestedAt,
                                }),
                            ],
                        };
                        const decision = decideGoalNextAction(resumed);
                        const blockedReason = decision.kind === "blocked" ? decision.reason : undefined;
                        const updated = await upsertGoalRun(cwd, {
                            ...resumed,
                            ...(blockedReason
                                ? {
                                    status: "blocked",
                                    continueRequestedAt: undefined,
                                    blockers: appendGoalBlockers(run.blockers, blockedReason),
                                    evidence: [
                                        ...resumed.evidence,
                                        createGoalEvidence({
                                            kind: "summary",
                                            label: "Goal resume blocked",
                                            content: blockedReason,
                                        }),
                                    ],
                                }
                                : {}),
                        });
                        await appendGoalDecision(cwd, updated.id, {
                            kind: "resume",
                            reason: decision.kind === "wait" ||
                                decision.kind === "blocked" ||
                                decision.kind === "terminal" ||
                                decision.kind === "complete" ||
                                decision.kind === "create_task" ||
                                decision.kind === "pause" ||
                                decision.kind === "start_worker" ||
                                decision.kind === "run_verifier"
                                ? decision.reason
                                : "Resume decision queued.",
                            content: `next=${decision.kind}`,
                        });
                        if (decision.kind === "wait") {
                            return `Goal "${updated.title}" resume queued: ${decision.reason}`;
                        }
                        if (decision.kind === "blocked") {
                            return `Goal "${updated.title}" resume blocked: ${decision.reason}`;
                        }
                        return `Goal "${updated.title}" resume requested; next action: ${decision.kind}.`;
                    }
                    else {
                        const completion = canCompleteGoalRun(run);
                        if (!completion.ok)
                            return `Error: cannot complete goal: ${completion.reason}`;
                        status = "passed";
                    }
                    const updated = await upsertGoalRun(cwd, { ...run, status });
                    return `Goal "${updated.title}" is now ${updated.status}.`;
                }
            }
        },
    };
}
//# sourceMappingURL=goals.js.map