"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createTaskAttemptContractReviseCommand = createTaskAttemptContractReviseCommand;
const errors_1 = require("../../../lib/errors");
const lifecycle_run_context_1 = require("../../../lib/lifecycle-run-context");
const output_1 = require("../../../lib/output");
const task_contract_revision_recovery_1 = require("../../../lib/planning/task-contract-revision-recovery");
const runtime_contract_1 = require("../../../lib/runtime/runtime-contract");
const global_format_1 = require("../global-format");
async function createTaskAttemptContractReviseCommand() {
    const { Command } = await import("commander");
    const command = new Command("attempt-contract-revise");
    command
        .description("Preview or atomically preserve one evidence-bearing stale attempt as checkpoint-bound contract_gap recovery.")
        .requiredOption("--revision-run-directory <path>", "Fresh full-cycle-strict run containing the accepted task-readiness contract revision. This is distinct from the global --run-directory lifecycle-capture binding.")
        .requiredOption("--task-definition <path>", "Repository-relative canonical task-definition.md path.")
        .requiredOption("--attempt-id <identity>", "Exact open evidence-bearing current attempt identity.")
        .requiredOption("--task-revision <revision>", "Exact current 64-character task revision after contract revision.")
        .requiredOption("--checkpoint-id <identity>", "Exact latest accepted contract-revision checkpoint identity.")
        .requiredOption("--recorded-by <actor>", "Non-empty recovery actor.")
        .requiredOption("--recorded-at <timestamp>", "ISO-8601 recovery time with explicit timezone.")
        .requiredOption("--reason <text>", "Non-empty reason for preserving the predecessor as contract_gap.")
        .option("--dry-run", "Preview exact run, checkpoint, pair, evidence, and transaction preconditions without mutation; omit to apply.")
        .action((_, commandInstance) => {
        const format = (0, output_1.resolveOutputFormat)((0, global_format_1.getGlobalFormat)(commandInstance));
        if (format === null)
            throw (0, errors_1.createUsageError)("Output format must be one of: text, json.");
        const repository = (0, runtime_contract_1.createRepositoryContext)((0, runtime_contract_1.detectRepositoryRoot)(), false);
        const options = commandInstance.opts();
        const request = {
            repositoryRoot: repository.root,
            runDirectory: options.revisionRunDirectory,
            taskDefinitionPath: options.taskDefinition,
            attemptId: options.attemptId,
            taskRevision: options.taskRevision,
            checkpointId: options.checkpointId,
            recordedBy: options.recordedBy,
            recordedAt: options.recordedAt,
            reason: options.reason,
        };
        let result;
        try {
            const preview = (0, task_contract_revision_recovery_1.previewTaskContractRevisionRecoverySync)(request);
            result = options.dryRun === true || preview.writeOutcome === "no-write"
                ? preview
                : (0, task_contract_revision_recovery_1.applyTaskContractRevisionRecoverySync)(preview);
        }
        catch (error) {
            throw normalizeError(error, request);
        }
        if (!["previewed", "committed", "no-write"].includes(result.writeOutcome)) {
            throw outcomeError(result);
        }
        (0, output_1.emitSuccess)({
            command: "task attempt-contract-revise",
            format,
            text: renderText(result),
            data: {
                ...result,
                repositoryRoot: repository.root,
                detectionSource: repository.detectionSource,
                nextAction: result.writeOutcome === "previewed"
                    ? applyAction(request)
                    : {
                        reasonCode: "fresh-readiness-required",
                        command: "task readiness-review",
                        argv: [
                            "day-shift", "task", "readiness-review",
                            "--task-definition", result.taskDefinitionPath,
                        ],
                        callable: false,
                        writeCapable: false,
                    },
            },
        });
    });
    command.addHelpText("after", [
        "",
        "Boundaries:",
        "  Eligibility requires the exact fresh full-cycle-strict run and latest accepted task-readiness contract-revision checkpoint.",
        "  Baseline-only attempts remain task attempt-supersede territory; this command requires post-baseline evidence.",
        "  Apply preserves predecessor evidence, records contract_gap audit metadata, clears current_attempt_id, and resets readiness without creating a successor.",
    ].join("\n"));
    return command;
}
function applyAction(request) {
    return {
        reasonCode: "apply-contract-revision-recovery",
        command: "task attempt-contract-revise",
        argv: [
            "day-shift", "task", "attempt-contract-revise",
            "--revision-run-directory", request.runDirectory,
            "--task-definition", request.taskDefinitionPath,
            "--attempt-id", request.attemptId,
            "--task-revision", request.taskRevision,
            "--checkpoint-id", request.checkpointId,
            "--recorded-by", request.recordedBy,
            "--recorded-at", request.recordedAt,
            "--reason", request.reason,
        ],
        callable: true,
        writeCapable: true,
    };
}
function normalizeError(error, request) {
    if (error instanceof errors_1.RuntimeError)
        return error;
    if (!(error instanceof task_contract_revision_recovery_1.TaskContractRevisionRecoveryError))
        throw error;
    const checkpointRepair = error.code === "checkpoint-conflict" ? createCheckpointRepairAction(request) : null;
    const refreshAction = (0, errors_1.createNonCallableRecoveryAction)({
        id: "recovery.task-attempt-contract-revise.refresh-exact-preview",
        command: "task attempt-contract-revise",
        explanation: "Refresh the exact run, checkpoint, task pair, attempt, and revision evidence before retrying.",
        reason: "The failure boundary cannot reconstruct stale or conflicting caller identities.",
    });
    const code = `TASK_ATTEMPT_CONTRACT_REVISE_${error.code.replace(/-/g, "_").toUpperCase()}`;
    const exitCode = error.code === "stale-task-revision" || error.code === "stale-preview"
        ? errors_1.RuntimeExitCode.STALE_EVIDENCE
        : error.code === "invalid-input"
            ? errors_1.RuntimeExitCode.USAGE
            : errors_1.RuntimeExitCode.INVALID_CONFIG;
    return new errors_1.RuntimeError({
        message: "Task attempt contract-revision recovery was rejected.",
        code,
        exitCode,
        writeOutcome: "no-writes",
        details: [
            error.message,
            "No task, summary, attempt, baseline, validation, checkpoint, run, or receipt evidence was rewritten or deleted.",
        ],
        findings: [{
                code,
                severity: "error",
                message: error.message,
                path: request.taskDefinitionPath,
                noWriteBoundary: "Rejected attempt-contract-revise transitions do not mutate the selected task pair or lifecycle run.",
            }],
        recoveryActions: checkpointRepair === null ? [refreshAction] : [checkpointRepair, refreshAction],
    });
}
function createCheckpointRepairAction(request) {
    try {
        const inspection = (0, lifecycle_run_context_1.inspectLifecycleRunContext)({
            repositoryRoot: request.repositoryRoot,
            runDirectory: request.runDirectory,
            selectedArtifactPath: request.taskDefinitionPath,
        });
        const checkpoint = inspection.manifest.contractRevisions.at(-1) ?? null;
        if (inspection.state !== "fresh" ||
            !inspection.manifestComplete ||
            checkpoint?.checkpointId !== request.checkpointId ||
            checkpoint.rollbackGate !== "task-readiness" ||
            checkpoint.oldActiveArtifactPath !== request.taskDefinitionPath ||
            checkpoint.newActiveArtifactPath !== request.taskDefinitionPath ||
            checkpoint.oldActiveArtifactHash !== checkpoint.newActiveArtifactHash)
            return null;
        const argv = [
            "day-shift", "resume", "run", "revise-contract",
            "--run-directory", request.runDirectory,
            "--review-result", checkpoint.reviewSourcePath,
            "--active-artifact", request.taskDefinitionPath,
            "--recorded-by", request.recordedBy,
            "--recorded-at", request.recordedAt,
            "--reason", "Repair the selected task binding on the accepted synchronized contract revision.",
            "--rollback-gate", "task-readiness",
            "--dry-run",
        ];
        const preview = (0, lifecycle_run_context_1.previewLifecycleRunContractRevisionSync)({
            repositoryRoot: request.repositoryRoot,
            runDirectory: request.runDirectory,
            reviewResultPath: checkpoint.reviewSourcePath,
            activeArtifactPath: request.taskDefinitionPath,
            recordedBy: request.recordedBy,
            recordedAt: request.recordedAt,
            reason: "Repair the selected task binding on the accepted synchronized contract revision.",
            rollbackGate: "task-readiness",
        });
        if (preview.writeOutcome !== "previewed" ||
            preview.checkpoint.oldActiveArtifactHash === preview.checkpoint.newActiveArtifactHash)
            return null;
        return (0, errors_1.createDescriptorBackedRecoveryAction)({
            command: "resume run revise-contract",
            argv,
            explanation: "Preview a deterministic additive checkpoint that repairs the selected task's proven predecessor/current revision binding without rewriting historical evidence.",
            selectedArtifactPath: request.taskDefinitionPath,
        });
    }
    catch {
        return null;
    }
}
function outcomeError(result) {
    const details = [
        `writeOutcome: ${result.writeOutcome}`,
        `intendedPaths: ${JSON.stringify(result.intendedPaths)}`,
        `changedPaths: ${JSON.stringify(result.changedPaths)}`,
        `conflicts: ${JSON.stringify(result.conflicts)}`,
        `recoveryPath: ${result.recoveryPath ?? "null"}`,
        `failure: ${result.failure ?? "null"}`,
    ];
    if (result.writeOutcome === "conflict") {
        return new errors_1.RuntimeError({
            message: "Task attempt-contract-revise preview is stale or conflicted.",
            code: "TASK_ATTEMPT_CONTRACT_REVISE_CONFLICT",
            exitCode: errors_1.RuntimeExitCode.CONCURRENCY_CONFLICT,
            writeOutcome: "no-writes",
            details,
        });
    }
    if (result.writeOutcome === "incomplete") {
        return new errors_1.RuntimeError({
            message: "Task attempt contract-revision recovery stopped with incomplete repository state.",
            code: "TASK_ATTEMPT_CONTRACT_REVISE_INCOMPLETE",
            exitCode: errors_1.RuntimeExitCode.PARTIAL_MUTATION,
            writeOutcome: "partial",
            details,
            recoveryActions: [(0, errors_1.createNonCallableRecoveryAction)({
                    id: "recovery.inspect-task-attempt-contract-revise-transaction",
                    explanation: "Inspect retained transaction evidence before retrying or repairing the task pair.",
                    reason: result.recoveryPath ?? "The retained transaction path was unavailable.",
                })],
        });
    }
    return new errors_1.RuntimeError({
        message: "Task attempt contract-revision recovery produced no canonical result.",
        code: "TASK_ATTEMPT_CONTRACT_REVISE_NO_WRITE",
        exitCode: errors_1.RuntimeExitCode.ERROR,
        details,
    });
}
function renderText(result) {
    return [
        "Task attempt contract-revision recovery",
        "",
        `Task definition: ${result.taskDefinitionPath}`,
        `Implementation summary: ${result.implementationSummaryPath}`,
        `Run: ${result.runDirectory}`,
        `Checkpoint: ${result.checkpointId}`,
        `Prior attempt: ${result.priorAttemptId}`,
        `Recovery ID: ${result.recoveryId}`,
        `Recovery state: ${result.recoveryState}`,
        `Old task revision: ${result.oldTaskRevision}`,
        `New task revision: ${result.newTaskRevision}`,
        `Preserved baseline: ${result.baselineId}`,
        `Evidence kinds: ${result.evidenceKinds.length}`,
        `Idempotent replay: ${result.idempotent ? "yes" : "no"}`,
        `Write outcome: ${result.writeOutcome}`,
    ].join("\n");
}
