"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TaskContractRevisionAdoptionError = void 0;
exports.discoverTaskContractRevisionAdoptionSync = discoverTaskContractRevisionAdoptionSync;
exports.previewTaskContractRevisionAdoptionSync = previewTaskContractRevisionAdoptionSync;
exports.applyTaskContractRevisionAdoptionSync = applyTaskContractRevisionAdoptionSync;
const node_crypto_1 = require("node:crypto");
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const node_util_1 = require("node:util");
const mutation_preconditions_1 = require("../filesystem/mutation-preconditions");
const repository_transaction_1 = require("../filesystem/repository-transaction");
const lifecycle_run_context_1 = require("../lifecycle-run-context");
const evidence_store_1 = require("../lifecycle-run-context/evidence-store");
const context_storage_1 = require("../lifecycle-run-context/context-storage");
const paths_1 = require("../paths");
const canonical_write_target_1 = require("../paths/canonical-write-target");
const sandbox_contract_1 = require("../paths/sandbox-contract");
const artifact_policy_projection_1 = require("./artifact-policy-projection");
const task_attempts_1 = require("./task-attempts");
const task_cycle_runtime_attribution_1 = require("./task-cycle-runtime-attribution");
const task_lifecycle_1 = require("./task-lifecycle");
const task_lifecycle_timestamps_1 = require("./task-lifecycle-timestamps");
const ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:-]{2,127}$/;
const SHA256_PATTERN = /^(?:sha256:)?[a-f0-9]{64}$/;
class TaskContractRevisionAdoptionError extends Error {
    code;
    constructor(code, message) {
        super(message);
        this.name = "TaskContractRevisionAdoptionError";
        this.code = code;
    }
}
exports.TaskContractRevisionAdoptionError = TaskContractRevisionAdoptionError;
const plans = new WeakMap();
function discoverTaskContractRevisionAdoptionSync(repositoryRootValue, taskDefinitionPath) {
    const pair = resolvePair(repositoryRootValue, taskDefinitionPath);
    const taskText = readUtf8(pair.task.runtimePath, pair.task.repositoryRelativePath);
    const summaryText = readUtf8(pair.summary.runtimePath, pair.summary.repositoryRelativePath);
    const taskRevision = sha256(taskText);
    const projection = (0, task_lifecycle_1.projectTaskLifecyclePair)({
        taskDefinition: taskText,
        implementationSummary: summaryText,
    });
    const current = projection.summary?.currentAttempt ?? null;
    if (projection.task.status !== "draft" ||
        projection.task.readiness !== "ready_to_implement" ||
        !projection.task.readinessAuthorization.complete ||
        !projection.task.readinessAuthorization.valid ||
        projection.task.readinessAuthorization.applicable ||
        current === null ||
        current.attemptId === null ||
        current.closedAt !== null ||
        current.reviewDisposition !== "pending" ||
        current.readinessReviewId === null)
        return [];
    const currentAttemptId = current.attemptId;
    const readinessReviewId = current.readinessReviewId;
    const inspections = inspectRuns(pair.repositoryRoot);
    const source = selectSourceLineage({
        pair,
        inspections,
        projection,
        currentAttemptId,
        readinessReviewId,
        currentTaskRevision: taskRevision,
    });
    if (source === null)
        return [];
    return inspections
        .filter((inspection) => inspection.state === "fresh" &&
        inspection.manifestComplete &&
        inspection.manifest.lifecycleProfile === "full-cycle-strict" &&
        inspection.manifest.runId !== source.inspection.manifest.runId &&
        inspection.manifest.activeArtifactPath === pair.task.repositoryRelativePath &&
        rawSha(inspection.manifest.activeArtifactHash) === taskRevision &&
        (inspection.manifest.contractRevisions.length === 0 ||
            (inspection.manifest.contractRevisions.length === 1 &&
                inspection.manifest.contractRevisions[0].adoptionSourceRunId === source.inspection.manifest.runId &&
                inspection.manifest.contractRevisions[0].adoptionSourceEntryId === source.entry.entryId &&
                rawSha(inspection.manifest.contractRevisions[0].newActiveArtifactHash) === taskRevision)) &&
        inspection.manifest.entries.length < lifecycle_run_context_1.MAX_ENTRIES)
        .map((inspection) => ({
        runDirectory: inspection.manifest.runDirectory,
        runId: inspection.manifest.runId,
        sourceRunDirectory: source.inspection.manifest.runDirectory,
        sourceRunId: source.inspection.manifest.runId,
        sourceEntryId: source.entry.entryId,
        sourceEvidencePath: source.entry.evidencePath,
        attemptId: currentAttemptId,
        checkpointId: adoptionCheckpointId({
            destinationRunId: inspection.manifest.runId,
            sourceRunId: source.inspection.manifest.runId,
            sourceEntryId: source.entry.entryId,
            attemptId: currentAttemptId,
            readinessReviewId,
            oldTaskRevision: rawSha(source.entry.artifactHash),
            newTaskRevision: taskRevision,
        }),
        oldTaskRevision: rawSha(source.entry.artifactHash),
        newTaskRevision: taskRevision,
    }))
        .sort((left, right) => left.runDirectory.localeCompare(right.runDirectory));
}
function previewTaskContractRevisionAdoptionSync(request) {
    validateRequest(request);
    const pair = resolvePair(request.repositoryRoot, request.taskDefinitionPath);
    const taskText = readUtf8(pair.task.runtimePath, pair.task.repositoryRelativePath);
    const summaryText = readUtf8(pair.summary.runtimePath, pair.summary.repositoryRelativePath);
    const observedTaskRevision = sha256(taskText);
    if (observedTaskRevision !== rawSha(request.taskRevision)) {
        throw new TaskContractRevisionAdoptionError("stale-task-revision", `Checkpoint adoption expected task revision '${rawSha(request.taskRevision)}', but current bytes are '${observedTaskRevision}'.`);
    }
    const projection = assertEligiblePair(pair, taskText, summaryText, request.attemptId);
    const current = projection.summary?.currentAttempt;
    if (current?.readinessReviewId === null || current?.readinessReviewId === undefined) {
        throw new TaskContractRevisionAdoptionError("pair-ineligible", "Checkpoint adoption requires the selected attempt's exact readiness identity.");
    }
    const inspections = inspectRuns(pair.repositoryRoot);
    const destination = inspections.find((inspection) => inspection.manifest.runDirectory === request.runDirectory) ?? null;
    const source = selectSourceLineage({
        pair,
        inspections,
        projection,
        currentAttemptId: request.attemptId,
        readinessReviewId: current.readinessReviewId,
        currentTaskRevision: observedTaskRevision,
        selectedSourceRunDirectory: request.sourceRunDirectory,
    });
    if (destination === null || source === null) {
        throw new TaskContractRevisionAdoptionError("lineage-mismatch", "The selected replacement/source run pair does not match one unambiguous predecessor readiness lineage.");
    }
    assertDestinationEligible(destination, pair.task.repositoryRelativePath, observedTaskRevision, source);
    const checkpointId = adoptionCheckpointId({
        destinationRunId: destination.manifest.runId,
        sourceRunId: source.inspection.manifest.runId,
        sourceEntryId: source.entry.entryId,
        attemptId: request.attemptId,
        readinessReviewId: current.readinessReviewId,
        oldTaskRevision: rawSha(source.entry.artifactHash),
        newTaskRevision: observedTaskRevision,
    });
    const replay = destination.manifest.contractRevisions.at(-1) ?? null;
    if (replay !== null) {
        return replayResult({ request, pair, destination, source, checkpointId, replay });
    }
    if (current.openedAt !== null && Date.parse(request.recordedAt) < Date.parse(current.openedAt)) {
        throw new TaskContractRevisionAdoptionError("invalid-input", "Checkpoint adoption cannot be recorded before the selected attempt opened.");
    }
    if (Date.parse(request.recordedAt) < Date.parse(source.entry.recordedAt)) {
        throw new TaskContractRevisionAdoptionError("invalid-input", "Checkpoint adoption cannot be recorded before the preserved source entry.");
    }
    const sequence = destination.manifest.nextSequence;
    const sequenceLabel = String(sequence).padStart(4, "0");
    const evidencePath = node_path_1.default.posix.join(destination.manifest.runDirectory, "evidence", `${sequenceLabel}-task-readiness-contract-revision-adoption-ok.json`);
    const importedEntryId = `lifecycle-entry-${sequenceLabel}-${sha256([
        destination.manifest.runId,
        String(sequence),
        "resume run revise-contract",
        pair.task.repositoryRelativePath,
        checkpointId,
    ].join("\u0000")).slice(0, 16)}`;
    const evidenceBytes = Buffer.from(`${JSON.stringify({
        protocolVersion: 2,
        status: "ok",
        command: "resume run revise-contract",
        data: {
            checkpointId,
            taskDefinitionPath: pair.task.repositoryRelativePath,
            attemptId: request.attemptId,
            readinessReviewId: current.readinessReviewId,
            oldTaskRevision: rawSha(source.entry.artifactHash),
            newTaskRevision: observedTaskRevision,
            sourceRunDirectory: source.inspection.manifest.runDirectory,
            sourceRunId: source.inspection.manifest.runId,
            sourceManifestRevision: source.inspection.manifestHash,
            sourceEntryId: source.entry.entryId,
            sourceEvidencePath: source.entry.evidencePath,
            sourceEvidenceHash: source.entry.evidenceHash,
            sourceEvidenceBytes: source.entry.evidenceBytes,
            sourceEvidenceVerified: true,
            sourceUnchanged: true,
            recordedBy: request.recordedBy.trim(),
            recordedAt: request.recordedAt,
            reason: request.reason.trim(),
            writeOutcome: "committed",
        },
        findings: [],
    }, null, 2)}\n`, "utf8");
    const importedEntry = {
        schemaVersion: 1,
        entryId: importedEntryId,
        sequence,
        commandIdentity: "resume run revise-contract",
        artifactPath: pair.task.repositoryRelativePath,
        artifactHash: source.entry.artifactHash,
        gate: "task-readiness",
        status: "ok",
        writeOutcome: "complete",
        receiptIds: [...new Set([current.readinessReviewId, source.entry.entryId])].sort(),
        supersedesEntryId: null,
        evidencePath,
        evidenceHash: prefixedSha256(evidenceBytes),
        evidenceBytes: evidenceBytes.byteLength,
        evidenceKind: "structured-success",
        errorCode: null,
        recordedAt: request.recordedAt,
    };
    const checkpoint = {
        schemaVersion: 1,
        checkpointId,
        recordedBy: request.recordedBy.trim(),
        recordedAt: request.recordedAt,
        reason: request.reason.trim(),
        rollbackGate: "task-readiness",
        reviewReceiptId: current.readinessReviewId,
        reviewSourcePath: source.entry.evidencePath,
        reviewSourceHash: source.entry.evidenceHash,
        reviewEvidencePath: evidencePath,
        reviewEntryId: importedEntry.entryId,
        oldPhaseHash: destination.manifest.phaseHash,
        newPhaseHash: destination.manifest.phaseHash,
        oldActiveArtifactPath: pair.task.repositoryRelativePath,
        oldActiveArtifactHash: source.entry.artifactHash,
        newActiveArtifactPath: pair.task.repositoryRelativePath,
        newActiveArtifactHash: destination.manifest.activeArtifactHash,
        invalidatedEntryIds: [importedEntry.entryId],
        adoptionSourceRunId: source.inspection.manifest.runId,
        adoptionSourceRunDirectory: source.inspection.manifest.runDirectory,
        adoptionSourceManifestHash: source.inspection.manifestHash,
        adoptionSourceEntryId: source.entry.entryId,
        adoptionSourceEvidenceHash: source.entry.evidenceHash,
    };
    const nextManifest = {
        ...destination.manifest,
        activeGate: "task-readiness",
        updatedAt: request.recordedAt,
        nextSequence: sequence + 1,
        entries: [...destination.manifest.entries, importedEntry],
        contractRevisions: [...destination.manifest.contractRevisions, checkpoint],
    };
    const manifestBytes = (0, context_storage_1.jsonBytes)(nextManifest, lifecycle_run_context_1.MAX_LIFECYCLE_RUN_MANIFEST_BYTES);
    const preconditions = adoptionPreconditions({ pair, destination, source, evidencePath });
    const writes = [
        { path: evidencePath, contents: evidenceBytes },
        { path: destination.manifestPath, contents: manifestBytes },
    ].sort((left, right) => left.path.localeCompare(right.path));
    const snapshot = resultSnapshot({
        pair,
        destination,
        source,
        request,
        checkpoint,
        importedEntry,
        manifestBytes,
        intendedPaths: writes.map((write) => write.path),
        expected: preconditions.map(toExpectedCondition),
        writeOutcome: "previewed",
        idempotent: false,
    });
    plans.set(snapshot, {
        repositoryRoot: pair.repositoryRoot,
        writes,
        preconditions,
        snapshot: cloneResult(snapshot),
        recordedAt: request.recordedAt,
    });
    return snapshot;
}
function applyTaskContractRevisionAdoptionSync(preview, options = {}) {
    if (preview.writeOutcome === "no-write" && preview.idempotent)
        return cloneResult(preview);
    const plan = plans.get(preview);
    if (plan === undefined) {
        throw new TaskContractRevisionAdoptionError("stale-preview", "Contract-revision checkpoint adoption apply requires the original in-process preview.");
    }
    (0, task_lifecycle_timestamps_1.revalidateObservedLifecycleTimestamp)(plan.recordedAt, "recorded_at", "Contract-revision adoption time");
    const transaction = (0, repository_transaction_1.executeRepositoryTransactionSync)(plan.repositoryRoot, { writes: plan.writes, preconditions: plan.preconditions }, options.transaction);
    return {
        ...cloneResult(plan.snapshot),
        changedPaths: transaction.entries.slice(0, transaction.canonicalWrites).map((entry) => entry.path),
        writeOutcome: transaction.outcome,
        transactionId: transaction.transactionId,
        conflicts: transaction.conflicts,
        recoveryPath: transaction.outcome === "incomplete" ? transaction.transactionPath : null,
        failure: transaction.failure ?? (transaction.cleanupErrors.length > 0 ? transaction.cleanupErrors.join(" ") : null),
    };
}
function assertEligiblePair(pair, taskText, summaryText, attemptId) {
    const projection = (0, task_lifecycle_1.projectTaskLifecyclePair)({ taskDefinition: taskText, implementationSummary: summaryText });
    const structuralBlockers = projection.blockingFindings.filter((finding) => finding.code !== "stale-readiness-authorization" &&
        finding.code !== "stale-attempt-readiness-reference");
    const current = projection.summary?.currentAttempt ?? null;
    if (structuralBlockers.length > 0 ||
        projection.task.status !== "draft" ||
        projection.task.readiness !== "ready_to_implement" ||
        !projection.task.readinessAuthorization.complete ||
        !projection.task.readinessAuthorization.valid ||
        projection.task.readinessAuthorization.applicable ||
        current?.attemptId !== attemptId ||
        current.closedAt !== null ||
        current.reviewDisposition !== "pending") {
        throw new TaskContractRevisionAdoptionError("pair-ineligible", "Checkpoint adoption requires the exact open evidence-bearing attempt with valid but stale readiness authorization.");
    }
    const baseline = (0, task_cycle_runtime_attribution_1.readAttemptRuntimeBaseline)(pair.summary.repositoryRelativePath, summaryText, attemptId);
    const evidenceProfile = (0, artifact_policy_projection_1.projectArtifactPolicy)(taskText).evidenceProfile;
    if (baseline === null && evidenceProfile !== "contract") {
        throw new TaskContractRevisionAdoptionError("pair-ineligible", "Checkpoint adoption requires the complete attempt-owned pre-write baseline.");
    }
    if (baseline !== null && (baseline.taskCycleId !== attemptId ||
        baseline.checkpointId !== current.readinessReviewId ||
        !baseline.capturedBeforeImplementationWrites ||
        !baseline.observationsComplete)) {
        throw new TaskContractRevisionAdoptionError("pair-ineligible", "Checkpoint adoption requires the exact complete attempt-owned pre-write baseline.");
    }
    const evidenceKinds = (0, task_attempts_1.inspectTaskAttemptSupersessionEvidence)(summaryText, attemptId);
    let targetDelta = [];
    if (baseline !== null) {
        try {
            targetDelta = (0, task_attempts_1.inspectSupersessionTargetDelta)(pair.repositoryRoot, pair.task.repositoryRelativePath, taskText, baseline);
        }
        catch (error) {
            if (error instanceof task_attempts_1.TaskAttemptSupersedeError) {
                throw new TaskContractRevisionAdoptionError("pair-ineligible", error.message);
            }
            throw error;
        }
    }
    if (evidenceKinds.length + targetDelta.length === 0) {
        throw new TaskContractRevisionAdoptionError("pair-ineligible", "Checkpoint adoption is reserved for evidence-bearing attempts; baseline-only attempts use task attempt-supersede.");
    }
    return projection;
}
function assertDestinationEligible(destination, taskPath, taskRevision, source) {
    const replay = destination.manifest.contractRevisions.at(-1) ?? null;
    const matchingReplay = replay !== null &&
        replay.adoptionSourceRunId === source.inspection.manifest.runId &&
        replay.adoptionSourceEntryId === source.entry.entryId &&
        rawSha(replay.newActiveArtifactHash) === taskRevision;
    if (destination.state !== "fresh" ||
        !destination.manifestComplete ||
        destination.manifest.lifecycleProfile !== "full-cycle-strict" ||
        destination.manifest.runId === source.inspection.manifest.runId ||
        destination.manifest.activeArtifactPath !== taskPath ||
        rawSha(destination.manifest.activeArtifactHash) !== taskRevision ||
        destination.manifest.entries.length >= lifecycle_run_context_1.MAX_ENTRIES ||
        (destination.manifest.contractRevisions.length !== 0 && !matchingReplay)) {
        throw new TaskContractRevisionAdoptionError("run-ineligible", "Adoption requires one fresh, complete full-cycle-strict replacement run with no unrelated contract-revision checkpoint.");
    }
}
function selectSourceLineage(options) {
    const predecessorRecoveryId = options.projection.summary?.currentAttempt?.predecessorContractRevisionRecoveryId ?? null;
    const expectedSourceRunIds = new Set((options.projection.summary?.attempts ?? [])
        .filter((attempt) => predecessorRecoveryId !== null && attempt.contractRevisionRecoveryId === predecessorRecoveryId)
        .map((attempt) => attempt.contractRevisionRunId)
        .filter((value) => value !== null));
    if (expectedSourceRunIds.size > 1)
        return null;
    const expectedSourceRunId = [...expectedSourceRunIds][0] ?? null;
    const matches = [];
    for (const inspection of options.inspections) {
        if (inspection.state !== "fresh" ||
            !inspection.manifestComplete ||
            inspection.manifest.lifecycleProfile !== "full-cycle-strict" ||
            (options.selectedSourceRunDirectory !== undefined &&
                inspection.manifest.runDirectory !== options.selectedSourceRunDirectory) ||
            (expectedSourceRunId !== null && inspection.manifest.runId !== expectedSourceRunId))
            continue;
        const inactive = (0, lifecycle_run_context_1.collectInactiveLifecycleEntryIds)(inspection.manifest);
        for (const entry of inspection.manifest.entries) {
            if (inactive.has(entry.entryId) ||
                entry.commandIdentity !== "task attempt-open" ||
                entry.artifactPath !== options.pair.task.repositoryRelativePath ||
                entry.status !== "ok" ||
                entry.writeOutcome !== "committed" ||
                !entry.receiptIds.includes(options.readinessReviewId) ||
                rawSha(entry.artifactHash) === options.currentTaskRevision)
                continue;
            let evidenceBytes;
            try {
                evidenceBytes = (0, evidence_store_1.readLifecycleEvidenceBytesSync)({
                    repositoryRoot: options.pair.repositoryRoot,
                    runDirectory: inspection.manifest.runDirectory,
                    entry,
                    maximumBytes: lifecycle_run_context_1.MAX_LIFECYCLE_RUN_RESULT_BYTES,
                }).bytes;
            }
            catch {
                continue;
            }
            if (!sourceAttemptOpenMatches(evidenceBytes, options.pair.task.repositoryRelativePath, options.currentAttemptId, options.readinessReviewId, rawSha(entry.artifactHash)))
                continue;
            matches.push({ inspection, entry, evidenceBytes });
        }
    }
    const identities = new Map();
    for (const match of matches) {
        const key = [
            match.inspection.manifest.runId,
            match.entry.entryId,
            match.entry.artifactHash,
            match.entry.evidenceHash,
        ].join("\u0000");
        identities.set(key, match);
    }
    return identities.size === 1 ? [...identities.values()][0] : null;
}
function sourceAttemptOpenMatches(bytes, taskPath, attemptId, readinessReviewId, oldTaskRevision) {
    try {
        const envelope = JSON.parse(bytes.toString("utf8"));
        const data = typeof envelope.data === "object" && envelope.data !== null && !Array.isArray(envelope.data)
            ? envelope.data
            : null;
        return envelope.status === "ok" &&
            envelope.command === "task attempt-open" &&
            data?.writeOutcome === "committed" &&
            data.taskDefinitionPath === taskPath &&
            data.attemptId === attemptId &&
            data.readinessReviewId === readinessReviewId &&
            data.taskRevision === oldTaskRevision;
    }
    catch {
        return false;
    }
}
function replayResult(options) {
    const { request, pair, destination, source, checkpointId, replay } = options;
    const importedEntry = destination.manifest.entries.find((entry) => entry.entryId === replay.reviewEntryId) ?? null;
    if (replay.checkpointId !== checkpointId ||
        replay.recordedBy !== request.recordedBy.trim() ||
        replay.recordedAt !== request.recordedAt ||
        replay.reason !== request.reason.trim() ||
        replay.adoptionSourceRunId !== source.inspection.manifest.runId ||
        replay.adoptionSourceRunDirectory !== source.inspection.manifest.runDirectory ||
        replay.adoptionSourceManifestHash !== source.inspection.manifestHash ||
        replay.adoptionSourceEntryId !== source.entry.entryId ||
        replay.adoptionSourceEvidenceHash !== source.entry.evidenceHash ||
        importedEntry === null) {
        throw new TaskContractRevisionAdoptionError("checkpoint-conflict", "The replacement run already contains a different contract-revision checkpoint.");
    }
    return resultSnapshot({
        pair,
        destination,
        source,
        request,
        checkpoint: replay,
        importedEntry,
        manifestBytes: Buffer.from(""),
        intendedPaths: [],
        expected: [],
        writeOutcome: "no-write",
        idempotent: true,
    });
}
function resultSnapshot(options) {
    return {
        runId: options.destination.manifest.runId,
        runDirectory: options.destination.manifest.runDirectory,
        manifestPath: options.destination.manifestPath,
        sourceRunId: options.source.inspection.manifest.runId,
        sourceRunDirectory: options.source.inspection.manifest.runDirectory,
        sourceManifestPath: options.source.inspection.manifestPath,
        sourceManifestRevision: options.source.inspection.manifestHash,
        sourceEntryId: options.source.entry.entryId,
        sourceEvidencePath: options.source.entry.evidencePath,
        sourceEvidenceHash: options.source.entry.evidenceHash,
        sourceUnchanged: true,
        taskDefinitionPath: options.pair.task.repositoryRelativePath,
        implementationSummaryPath: options.pair.summary.repositoryRelativePath,
        priorAttemptId: options.request.attemptId,
        checkpointId: options.checkpoint.checkpointId,
        oldTaskRevision: rawSha(options.checkpoint.oldActiveArtifactHash),
        newTaskRevision: rawSha(options.checkpoint.newActiveArtifactHash),
        checkpoint: { ...options.checkpoint, invalidatedEntryIds: [...options.checkpoint.invalidatedEntryIds] },
        importedEntry: { ...options.importedEntry, receiptIds: [...options.importedEntry.receiptIds] },
        manifestRevision: options.destination.manifestHash,
        nextManifestRevision: options.idempotent
            ? options.destination.manifestHash
            : prefixedSha256(options.manifestBytes),
        idempotent: options.idempotent,
        intendedPaths: [...options.intendedPaths],
        changedPaths: [],
        expected: options.expected.map((entry) => ({ ...entry })),
        writeOutcome: options.writeOutcome,
        transactionId: null,
        conflicts: [],
        recoveryPath: null,
        failure: null,
    };
}
function adoptionPreconditions(options) {
    const sourceEvidencePath = options.source.entry.evidenceStorage?.objectPath ?? options.source.entry.evidencePath;
    const presentPaths = [...new Set([
            options.pair.task.repositoryRelativePath,
            options.pair.summary.repositoryRelativePath,
            options.destination.manifest.phasePath,
            options.destination.manifestPath,
            options.source.inspection.manifestPath,
            sourceEvidencePath,
        ])].sort();
    const preconditions = [];
    for (const repositoryPath of presentPaths) {
        const target = (0, canonical_write_target_1.resolveCanonicalWriteTargetSync)(options.pair.repositoryRoot, repositoryPath);
        preconditions.push((0, mutation_preconditions_1.captureDestinationPresencePreconditionSync)(target));
        preconditions.push((0, mutation_preconditions_1.captureContentRevisionPreconditionSync)(target));
    }
    preconditions.push((0, mutation_preconditions_1.captureDestinationPresencePreconditionSync)((0, canonical_write_target_1.resolveCanonicalWriteTargetSync)(options.pair.repositoryRoot, options.evidencePath)));
    return preconditions;
}
function inspectRuns(repositoryRoot) {
    const inspections = [];
    const seen = new Set();
    for (const runParent of [sandbox_contract_1.SANDBOX_PARENT_DIRECTORY, sandbox_contract_1.LEGACY_SANDBOX_PARENT_DIRECTORY]) {
        const parent = node_path_1.default.join(repositoryRoot, runParent);
        let directories;
        try {
            directories = node_fs_1.default.readdirSync(parent, { withFileTypes: true });
        }
        catch {
            continue;
        }
        for (const entry of directories
            .filter((candidate) => candidate.isDirectory() && candidate.name.startsWith("run-"))
            .sort((left, right) => left.name.localeCompare(right.name))
            .slice(0, 512)) {
            const runDirectory = node_path_1.default.posix.join(runParent, entry.name);
            if (seen.has(runDirectory))
                continue;
            seen.add(runDirectory);
            try {
                inspections.push((0, lifecycle_run_context_1.inspectLifecycleRunContext)({ repositoryRoot, runDirectory }));
            }
            catch {
                continue;
            }
        }
    }
    return inspections;
}
function resolvePair(repositoryRootValue, taskDefinitionPath) {
    const repositoryRoot = node_fs_1.default.realpathSync(node_path_1.default.resolve(requireText(repositoryRootValue, "Repository root")));
    let parsed;
    try {
        parsed = (0, paths_1.parseRepositoryRelativePath)(taskDefinitionPath);
    }
    catch (error) {
        throw new TaskContractRevisionAdoptionError("invalid-input", error instanceof Error ? error.message : "Invalid task-definition path.");
    }
    if (parsed.segments.at(-1) !== "task-definition.md") {
        throw new TaskContractRevisionAdoptionError("invalid-input", "Adoption paths must end in task-definition.md.");
    }
    const task = (0, canonical_write_target_1.resolveCanonicalWriteTargetSync)(repositoryRoot, parsed.normalizedPath);
    const summary = (0, canonical_write_target_1.resolveCanonicalWriteTargetSync)(repositoryRoot, [...parsed.segments.slice(0, -1), "implementation-summary.md"].join("/"));
    if (!task.exists || !summary.exists) {
        throw new TaskContractRevisionAdoptionError("artifact-unreadable", "Both task-definition.md and implementation-summary.md must exist.");
    }
    return { repositoryRoot, task, summary };
}
function validateRequest(request) {
    requireText(request.runDirectory, "Replacement run directory");
    requireText(request.sourceRunDirectory, "Source run directory");
    requireId(request.attemptId, "Attempt identity");
    if (!SHA256_PATTERN.test(requireText(request.taskRevision, "Task revision"))) {
        throw new TaskContractRevisionAdoptionError("invalid-input", "Task revision must be an exact SHA-256 revision.");
    }
    requireText(request.recordedBy, "Adoption actor");
    requireText(request.reason, "Adoption reason");
    if (!(0, task_lifecycle_1.isTaskLifecycleTimestamp)(request.recordedAt)) {
        throw new TaskContractRevisionAdoptionError("invalid-input", "Adoption time must be an ISO-8601 timestamp with an explicit timezone.");
    }
    (0, task_lifecycle_timestamps_1.requireObservedLifecycleTimestamp)({
        value: request.recordedAt,
        field: "recorded_at",
        label: "Contract-revision adoption time",
    });
}
function readUtf8(runtimePath, relativePath) {
    const stats = node_fs_1.default.statSync(runtimePath, { throwIfNoEntry: false });
    if (stats === undefined || !stats.isFile()) {
        throw new TaskContractRevisionAdoptionError("artifact-unreadable", `Artifact '${relativePath}' must be a regular file.`);
    }
    try {
        return new node_util_1.TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(node_fs_1.default.readFileSync(runtimePath));
    }
    catch (error) {
        throw new TaskContractRevisionAdoptionError("artifact-unreadable", `Artifact '${relativePath}' must contain valid UTF-8: ${error instanceof Error ? error.message : String(error)}`);
    }
}
function adoptionCheckpointId(input) {
    return `lifecycle-contract-revision-adoption-${sha256(JSON.stringify(input)).slice(0, 24)}`;
}
function requireId(value, label) {
    const identity = requireText(value, label);
    if (!ID_PATTERN.test(identity)) {
        throw new TaskContractRevisionAdoptionError("invalid-input", `${label} must use 3-128 machine-safe characters.`);
    }
    return identity;
}
function requireText(value, label) {
    if (typeof value !== "string" || value.trim() === "") {
        throw new TaskContractRevisionAdoptionError("invalid-input", `${label} must be non-empty.`);
    }
    return value.trim();
}
function rawSha(value) {
    return value.startsWith("sha256:") ? value.slice("sha256:".length) : value;
}
function sha256(value) {
    return (0, node_crypto_1.createHash)("sha256").update(value).digest("hex");
}
function prefixedSha256(value) {
    return `sha256:${sha256(value)}`;
}
function toExpectedCondition(precondition) {
    return {
        path: precondition.repositoryRelativePath,
        kind: precondition.kind,
        expectedState: precondition.kind === "content-revision"
            ? precondition.expectedRevision
            : precondition.expectedPresence,
    };
}
function cloneResult(result) {
    return {
        ...result,
        checkpoint: { ...result.checkpoint, invalidatedEntryIds: [...result.checkpoint.invalidatedEntryIds] },
        importedEntry: { ...result.importedEntry, receiptIds: [...result.importedEntry.receiptIds] },
        intendedPaths: [...result.intendedPaths],
        changedPaths: [...result.changedPaths],
        expected: result.expected.map((entry) => ({ ...entry })),
        conflicts: result.conflicts.map((entry) => ({ ...entry })),
    };
}
