"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.VALIDATION_AND_READINESS_COMMAND_EVIDENCE_CATEGORIES = exports.VALIDATION_RECOVERY_NEXT_ACTIONS = exports.VALIDATION_ADVISORY_FINDING_POLICY = exports.VALIDATION_ADVISORY_REASONS = exports.VALIDATION_BLOCKING_FINDING_POLICY = exports.VALIDATION_BLOCKING_REASONS = exports.VALIDATION_FINDING_LEVEL_POLICY = exports.VALIDATION_FINDING_LEVELS = exports.TRACE_LINK_FINDING_TAXONOMY = exports.TRACE_LINK_FINDING_IDS = exports.getValidationReadOnlyFailureContract = exports.VALIDATION_READ_ONLY_FAILURE_CONTRACT = exports.getValidationCommandOutputContracts = exports.VALIDATION_FINDING_JSON_OUTPUT_CONTRACT = exports.VALIDATION_COMMAND_REUSE_POLICY = exports.VALIDATION_COMMAND_OUTPUT_CONTRACTS = exports.TRACE_LINK_TRAVERSAL_BOUNDARIES = exports.TRACE_LINK_RESOLUTION_RULES = exports.TRACE_LINK_HIERARCHY_RULES = exports.TRACEABLE_ARTIFACT_COVERAGE = void 0;
exports.resolveLocalTraceLinkValue = resolveLocalTraceLinkValue;
exports.compareExplicitTraceLinkTarget = compareExplicitTraceLinkTarget;
exports.createValidationFinding = createValidationFinding;
exports.createBlockingValidationFinding = createBlockingValidationFinding;
exports.createAdvisoryValidationFinding = createAdvisoryValidationFinding;
exports.createTraceLinkValidationFinding = createTraceLinkValidationFinding;
exports.createValidationArtifactReference = createValidationArtifactReference;
exports.createValidationAffectedPath = createValidationAffectedPath;
exports.createValidationCommandEvidence = createValidationCommandEvidence;
exports.renderValidationFindingsText = renderValidationFindingsText;
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const paths_1 = require("../paths");
const validation_trace_contracts_1 = require("./validation-trace-contracts");
const validation_trace_taxonomy_1 = require("./validation-trace-taxonomy");
var validation_trace_contracts_2 = require("./validation-trace-contracts");
Object.defineProperty(exports, "TRACEABLE_ARTIFACT_COVERAGE", { enumerable: true, get: function () { return validation_trace_contracts_2.TRACEABLE_ARTIFACT_COVERAGE; } });
Object.defineProperty(exports, "TRACE_LINK_HIERARCHY_RULES", { enumerable: true, get: function () { return validation_trace_contracts_2.TRACE_LINK_HIERARCHY_RULES; } });
Object.defineProperty(exports, "TRACE_LINK_RESOLUTION_RULES", { enumerable: true, get: function () { return validation_trace_contracts_2.TRACE_LINK_RESOLUTION_RULES; } });
Object.defineProperty(exports, "TRACE_LINK_TRAVERSAL_BOUNDARIES", { enumerable: true, get: function () { return validation_trace_contracts_2.TRACE_LINK_TRAVERSAL_BOUNDARIES; } });
var validation_output_contracts_1 = require("./validation-output-contracts");
Object.defineProperty(exports, "VALIDATION_COMMAND_OUTPUT_CONTRACTS", { enumerable: true, get: function () { return validation_output_contracts_1.VALIDATION_COMMAND_OUTPUT_CONTRACTS; } });
Object.defineProperty(exports, "VALIDATION_COMMAND_REUSE_POLICY", { enumerable: true, get: function () { return validation_output_contracts_1.VALIDATION_COMMAND_REUSE_POLICY; } });
Object.defineProperty(exports, "VALIDATION_FINDING_JSON_OUTPUT_CONTRACT", { enumerable: true, get: function () { return validation_output_contracts_1.VALIDATION_FINDING_JSON_OUTPUT_CONTRACT; } });
Object.defineProperty(exports, "getValidationCommandOutputContracts", { enumerable: true, get: function () { return validation_output_contracts_1.getValidationCommandOutputContracts; } });
var validation_read_only_contracts_1 = require("./validation-read-only-contracts");
Object.defineProperty(exports, "VALIDATION_READ_ONLY_FAILURE_CONTRACT", { enumerable: true, get: function () { return validation_read_only_contracts_1.VALIDATION_READ_ONLY_FAILURE_CONTRACT; } });
Object.defineProperty(exports, "getValidationReadOnlyFailureContract", { enumerable: true, get: function () { return validation_read_only_contracts_1.getValidationReadOnlyFailureContract; } });
var validation_trace_taxonomy_2 = require("./validation-trace-taxonomy");
Object.defineProperty(exports, "TRACE_LINK_FINDING_IDS", { enumerable: true, get: function () { return validation_trace_taxonomy_2.TRACE_LINK_FINDING_IDS; } });
Object.defineProperty(exports, "TRACE_LINK_FINDING_TAXONOMY", { enumerable: true, get: function () { return validation_trace_taxonomy_2.TRACE_LINK_FINDING_TAXONOMY; } });
exports.VALIDATION_FINDING_LEVELS = ["informational", "warning", "error"];
exports.VALIDATION_FINDING_LEVEL_POLICY = {
    informational: {
        level: "informational",
        severity: "informational",
        meaning: "Context, successful evidence, or non-actionable observations for humans and automation logs.",
        automationSemantics: "Does not block automation and should not require recovery guidance.",
        reviewSemantics: "May provide traceability or diagnostic context without implying a review concern."
    },
    warning: {
        level: "warning",
        severity: "warning",
        meaning: "Advisory evidence that may need human review, follow-up work, or recovery guidance.",
        automationSemantics: "Does not define a blocking outcome by itself; downstream boundary policy decides when a warning should stop a write.",
        reviewSemantics: "Use for weak evidence, possible discovered work, backlog candidates, and impact questions."
    },
    error: {
        level: "error",
        severity: "error",
        meaning: "A validation failure or unsafe condition that automation consumers must treat as the highest severity.",
        automationSemantics: "Compatible with blocking-oriented outcomes, but concrete blocking boundaries are assigned by command policy.",
        reviewSemantics: "Use when evidence indicates broken traceability, invalid input, unsafe scope mismatch, or another failed invariant."
    }
};
exports.VALIDATION_BLOCKING_REASONS = [
    "broken-traceability",
    "invalid-command-input",
    "unsafe-scope-mismatch"
];
exports.VALIDATION_BLOCKING_FINDING_POLICY = {
    "broken-traceability": {
        reason: "broken-traceability",
        level: "error",
        noWriteRequired: true,
        meaning: "A local repository-relative trace link or required artifact relationship is broken.",
        recoveryExpectation: "Repair the missing or stale trace target, then rerun the command from the original input."
    },
    "invalid-command-input": {
        reason: "invalid-command-input",
        level: "error",
        noWriteRequired: true,
        meaning: "The command input is unsupported, malformed, contradictory, or unsafe to interpret.",
        recoveryExpectation: "Correct the command input or artifact metadata, then rerun without relying on guessed partial writes."
    },
    "unsafe-scope-mismatch": {
        reason: "unsafe-scope-mismatch",
        level: "error",
        noWriteRequired: true,
        meaning: "The requested write or automation target does not match the declared task, milestone, or artifact scope.",
        recoveryExpectation: "Realign the request with declared scope or create explicit follow-up planning before rerunning."
    }
};
exports.VALIDATION_ADVISORY_REASONS = [
    "weak-evidence",
    "possible-discovered-work",
    "backlog-candidate",
    "impact-question"
];
exports.VALIDATION_ADVISORY_FINDING_POLICY = {
    "weak-evidence": {
        reason: "weak-evidence",
        defaultLevel: "warning",
        allowedLevels: ["warning", "informational"],
        noWriteRequired: false,
        meaning: "Evidence is incomplete, stale, placeholder-like, or insufficient for a reviewer to rely on without follow-up.",
        recoveryExpectation: "Review the cited evidence and add deterministic validation, notes, or closeout detail before relying on it."
    },
    "possible-discovered-work": {
        reason: "possible-discovered-work",
        defaultLevel: "warning",
        allowedLevels: ["warning", "informational"],
        noWriteRequired: false,
        meaning: "The finding may represent work discovered during validation, but it does not make the current read-only report unsafe.",
        recoveryExpectation: "Confirm whether the item is in scope, then capture it in planning or a follow-up task instead of applying guessed repairs."
    },
    "backlog-candidate": {
        reason: "backlog-candidate",
        defaultLevel: "warning",
        allowedLevels: ["warning", "informational"],
        noWriteRequired: false,
        meaning: "The finding may belong in backlog or future planning rather than the current automation step.",
        recoveryExpectation: "Route the candidate through planning or backlog triage before treating it as current implementation scope."
    },
    "impact-question": {
        reason: "impact-question",
        defaultLevel: "warning",
        allowedLevels: ["warning", "informational"],
        noWriteRequired: false,
        meaning: "The finding raises an impact or review question that needs human interpretation.",
        recoveryExpectation: "Review the impact question and record a decision, follow-up, or non-issue note before downstream handoff."
    }
};
exports.VALIDATION_RECOVERY_NEXT_ACTIONS = [
    "none",
    "review-scope",
    "revise-planning",
    "capture-discovered-work",
    "route-backlog",
    "correct-input",
    "stop-unsafe-automation"
];
function resolveLocalTraceLinkValue(options) {
    const originalValue = options.value;
    if (isUnsupportedExternalTraceReference(originalValue)) {
        return {
            status: "unsupported-external-reference",
            originalValue,
            message: "Trace value is outside local links-check coverage."
        };
    }
    let parsedPath;
    try {
        parsedPath = (0, paths_1.parseRepositoryRelativePath)(originalValue);
    }
    catch (error) {
        return {
            status: "malformed-local-link",
            originalValue,
            message: error instanceof Error ? error.message : "Trace value is not a valid repository-relative path."
        };
    }
    const traversalBoundary = findTraceLinkTraversalBoundary(parsedPath.normalizedPath, options.traversalBoundaries ?? validation_trace_contracts_1.TRACE_LINK_TRAVERSAL_BOUNDARIES);
    if (traversalBoundary === null) {
        return {
            status: "outside-traversal-boundary",
            originalValue,
            normalizedPath: parsedPath.normalizedPath,
            message: "Trace value is outside declared local trace traversal roots."
        };
    }
    const absolutePath = node_path_1.default.resolve(options.repositoryRoot, parsedPath.normalizedPath);
    if (!node_fs_1.default.existsSync(absolutePath)) {
        return {
            status: "missing-local-target",
            originalValue,
            normalizedPath: parsedPath.normalizedPath,
            absolutePath,
            traversalBoundary,
            message: "Trace value is well-formed, but the local target does not exist."
        };
    }
    return {
        status: "resolved-local-target",
        originalValue,
        normalizedPath: parsedPath.normalizedPath,
        absolutePath,
        traversalBoundary,
        message: "Trace value resolved to an existing local target."
    };
}
function compareExplicitTraceLinkTarget(options) {
    const actualPath = (0, paths_1.parseRepositoryRelativePath)(options.actualValue);
    const expectedPath = (0, paths_1.parseRepositoryRelativePath)(options.expectedPath);
    const sourceArtifactPath = (0, paths_1.parseRepositoryRelativePath)(options.sourceArtifactPath);
    if (actualPath.normalizedPath === expectedPath.normalizedPath) {
        return {
            status: "hierarchy-match",
            relationship: options.relationship,
            sourceArtifactPath: sourceArtifactPath.normalizedPath,
            field: options.field,
            originalValue: actualPath.originalInput,
            normalizedActualPath: actualPath.normalizedPath,
            normalizedExpectedPath: expectedPath.normalizedPath,
            message: "Explicit trace-link metadata matches the expected local target."
        };
    }
    const mismatchStatus = options.mismatchStatus ?? "hierarchy-mismatch";
    return {
        status: mismatchStatus,
        relationship: options.relationship,
        sourceArtifactPath: sourceArtifactPath.normalizedPath,
        field: options.field,
        originalValue: actualPath.originalInput,
        normalizedActualPath: actualPath.normalizedPath,
        normalizedExpectedPath: expectedPath.normalizedPath,
        message: mismatchStatus === "stale-link"
            ? "Explicit trace-link metadata points to a stale target."
            : "Explicit trace-link metadata points outside the expected artifact hierarchy."
    };
}
function isUnsupportedExternalTraceReference(value) {
    return /^[A-Za-z][A-Za-z0-9+.-]*:\/\//u.test(value) ||
        /^git(?:hub|lab|ea)?[:/]/iu.test(value) ||
        /^npm:/iu.test(value) ||
        /^pkg:/iu.test(value);
}
function findTraceLinkTraversalBoundary(normalizedPath, traversalBoundaries) {
    for (const boundary of traversalBoundaries) {
        if (boundary === ".") {
            return boundary;
        }
        if (normalizedPath === boundary || normalizedPath.startsWith(`${boundary}/`)) {
            return boundary;
        }
    }
    return null;
}
exports.VALIDATION_AND_READINESS_COMMAND_EVIDENCE_CATEGORIES = [
    "validation-rollup",
    "links-check",
    "scope-guard",
    "diff-check",
    "impact-analysis"
];
function createValidationFinding(input) {
    const { advisoryReason: _advisoryReason, blockingReason: _blockingReason, ...findingInput } = input;
    const code = input.code ?? input.id;
    const message = input.message ?? input.summary;
    const severity = input.severity ?? input.level;
    const details = input.evidence?.details;
    if (code === undefined || code.trim() === "") {
        throw new TypeError("Validation finding requires a stable code or id.");
    }
    if (message === undefined || message.trim() === "") {
        throw new TypeError("Validation finding requires a message or summary.");
    }
    if (severity === undefined) {
        throw new TypeError("Validation finding requires a severity or level.");
    }
    return {
        ...findingInput,
        id: input.id ?? code,
        code,
        summary: input.summary ?? message,
        message,
        level: input.level ?? severity,
        severity,
        ruleFamily: input.ruleFamily ?? getStringDetail(details, "ruleFamily"),
        artifactPath: input.artifactPath ?? input.path ?? input.artifacts?.[0]?.path,
        evidenceSource: input.evidenceSource ?? getStringDetail(details, "evidenceSource") ?? input.evidence?.category,
        reason: input.reason
            ?? getStringDetail(details, "reason")
            ?? getStringDetail(details, "blockingReason")
            ?? getStringDetail(details, "advisoryReason")
            ?? getStringDetail(details, "noWriteReason"),
        noWriteBoundary: input.noWriteBoundary ?? getStringDetail(details, "noWriteBoundary"),
        recommendedCommand: input.recommendedCommand
            ?? getStringDetail(details, "recommendedCommand")
            ?? getStringDetail(details, "nextAction")
    };
}
function getStringDetail(details, key) {
    const value = details?.[key];
    return typeof value === "string" && value.trim() !== "" ? value : undefined;
}
function createBlockingValidationFinding(input) {
    const policy = exports.VALIDATION_BLOCKING_FINDING_POLICY[input.blockingReason];
    const details = {
        ...input.evidence?.details,
        blockingReason: input.blockingReason,
        noWriteRequired: policy.noWriteRequired
    };
    return createValidationFinding({
        ...input,
        level: policy.level,
        severity: policy.level,
        recovery: input.recovery,
        evidence: {
            category: input.evidence?.category ?? "command-specific",
            details
        }
    });
}
function createAdvisoryValidationFinding(input) {
    const policy = exports.VALIDATION_ADVISORY_FINDING_POLICY[input.advisoryReason];
    const level = input.level ?? policy.defaultLevel;
    const details = {
        ...input.evidence?.details,
        advisoryReason: input.advisoryReason,
        noWriteRequired: policy.noWriteRequired
    };
    return createValidationFinding({
        ...input,
        level,
        severity: level,
        recovery: input.recovery,
        evidence: {
            category: input.evidence?.category ?? "planning-review",
            details
        }
    });
}
function createTraceLinkValidationFinding(options) {
    const taxonomy = validation_trace_taxonomy_1.TRACE_LINK_FINDING_TAXONOMY.find((entry) => entry.id === options.taxonomyId);
    if (taxonomy === undefined) {
        throw new TypeError(`Unsupported trace-link finding taxonomy id '${options.taxonomyId}'.`);
    }
    const artifacts = [
        createValidationArtifactReference(options.artifact, { repositoryRoot: options.repositoryRoot })
    ];
    const affectedPaths = [
        createValidationAffectedPath(options.affectedPath, { repositoryRoot: options.repositoryRoot })
    ];
    const evidence = createValidationCommandEvidence({
        category: taxonomy.evidenceCategory,
        details: {
            taxonomyId: taxonomy.id,
            relationship: options.relationship,
            field: options.field,
            ...(options.traceValue !== undefined ? { traceValue: options.traceValue } : {}),
            ...(options.expectedPath !== undefined ? { expectedPath: options.expectedPath } : {}),
            ...(options.resolutionStatus !== undefined ? { resolutionStatus: options.resolutionStatus } : {}),
            ...(options.hierarchyStatus !== undefined ? { hierarchyStatus: options.hierarchyStatus } : {}),
            ...options.evidenceDetails
        }
    });
    if (taxonomy.blockingReason !== undefined) {
        return createBlockingValidationFinding({
            id: taxonomy.id,
            summary: taxonomy.summary,
            detail: options.detail,
            artifacts,
            affectedPaths,
            blockingReason: taxonomy.blockingReason,
            recovery: options.recovery ?? taxonomy.recovery,
            evidence
        });
    }
    if (taxonomy.advisoryReason !== undefined) {
        return createAdvisoryValidationFinding({
            id: taxonomy.id,
            summary: taxonomy.summary,
            detail: options.detail,
            level: taxonomy.defaultLevel === "informational" ? "informational" : "warning",
            artifacts,
            affectedPaths,
            advisoryReason: taxonomy.advisoryReason,
            recovery: options.recovery ?? taxonomy.recovery,
            evidence
        });
    }
    return createValidationFinding({
        id: taxonomy.id,
        summary: taxonomy.summary,
        detail: options.detail,
        level: taxonomy.defaultLevel,
        artifacts,
        affectedPaths,
        recovery: taxonomy.recovery,
        evidence
    });
}
function createValidationArtifactReference(input, options = {}) {
    return {
        ...input,
        path: normalizeValidationFindingPath(input.path, options),
        sourceType: input.sourceType ?? input.source?.sourceType
    };
}
function createValidationAffectedPath(input, options = {}) {
    return {
        ...input,
        path: normalizeValidationFindingPath(input.path, options),
        artifact: input.artifact === undefined
            ? undefined
            : createValidationArtifactReference(input.artifact, options)
    };
}
function createValidationCommandEvidence(input) {
    return {
        category: input.category,
        details: input.details
    };
}
function renderValidationFindingsText(findings, heading = "Findings") {
    const lines = [`${heading}:`];
    if (findings.length === 0) {
        lines.push("- (none)");
        return lines.join("\n");
    }
    for (const finding of findings) {
        const identity = finding.id ?? finding.code;
        const level = finding.level ?? finding.severity;
        lines.push(`- [${level}] ${identity}: ${finding.summary ?? finding.message}`);
        if (finding.detail !== undefined && finding.detail.trim() !== "") {
            lines.push(`  Detail: ${finding.detail}`);
        }
        if (finding.ruleFamily !== undefined && finding.ruleFamily.trim() !== "") {
            lines.push(`  Rule family: ${finding.ruleFamily}`);
        }
        if (finding.artifactPath !== undefined && finding.artifactPath.trim() !== "") {
            lines.push(`  Artifact path: ${finding.artifactPath}`);
        }
        if (finding.evidenceSource !== undefined && finding.evidenceSource.trim() !== "") {
            lines.push(`  Evidence source: ${finding.evidenceSource}`);
        }
        if (finding.reason !== undefined && finding.reason.trim() !== "") {
            lines.push(`  Reason: ${finding.reason}`);
        }
        if (finding.noWriteBoundary !== undefined && finding.noWriteBoundary.trim() !== "") {
            lines.push(`  No-write boundary: ${finding.noWriteBoundary}`);
        }
        if (finding.recommendedCommand !== undefined && finding.recommendedCommand.trim() !== "") {
            lines.push(`  Recommended command: ${finding.recommendedCommand}`);
        }
        if (finding.path !== undefined && finding.path.trim() !== "") {
            lines.push(`  Path: ${finding.path}`);
        }
        if (finding.affectedPaths !== undefined && finding.affectedPaths.length > 0) {
            lines.push("  Affected paths:");
            for (const affectedPath of finding.affectedPaths) {
                const description = affectedPath.description === undefined
                    ? ""
                    : ` - ${affectedPath.description}`;
                lines.push(`  - ${affectedPath.role}: ${affectedPath.path}${description}`);
            }
        }
        if (finding.artifacts !== undefined && finding.artifacts.length > 0) {
            lines.push("  Artifacts:");
            for (const artifact of finding.artifacts) {
                const label = artifact.id ?? artifact.artifactType ?? artifact.family;
                lines.push(`  - ${artifact.family}: ${artifact.path} (${label})`);
            }
        }
        if (finding.recovery !== undefined) {
            lines.push("  Recovery:");
            const recoveryItems = Array.isArray(finding.recovery)
                ? finding.recovery
                : [finding.recovery];
            for (const recovery of recoveryItems) {
                lines.push(`  - ${recovery}`);
            }
        }
        if (finding.evidence !== undefined) {
            lines.push(`  Evidence category: ${finding.evidence.category}`);
            const details = finding.evidence.details;
            if (details !== undefined) {
                if (typeof details.category === "string") {
                    lines.push(`  Classification: ${details.category}`);
                }
                if (typeof details.command === "string") {
                    lines.push(`  Command: ${details.command}`);
                }
                if (typeof details.capability === "string") {
                    lines.push(`  Command capability: ${details.capability}`);
                }
                if (typeof details.primaryCapability === "string") {
                    lines.push(`  Primary capability: ${details.primaryCapability}`);
                }
                if (typeof details.family === "string") {
                    lines.push(`  Family: ${details.family}`);
                }
                if (typeof details.artifactFamily === "string") {
                    lines.push(`  Artifact family: ${details.artifactFamily}`);
                }
                if (typeof details.coordinationScope === "string") {
                    lines.push(`  Coordination scope: ${details.coordinationScope}`);
                }
                if (typeof details.mutationPosture === "string") {
                    lines.push(`  Mutation posture: ${details.mutationPosture}`);
                }
                if (typeof details.writeCapable === "boolean") {
                    lines.push(`  Write capable: ${details.writeCapable ? "yes" : "no"}`);
                }
                if (typeof details.field === "string") {
                    lines.push(`  Field: ${details.field}`);
                }
                if (typeof details.detectedVersion === "number" || details.detectedVersion === null) {
                    lines.push(`  Detected version: ${details.detectedVersion === null ? "unknown" : details.detectedVersion}`);
                }
                if (typeof details.supportedRange === "object" &&
                    details.supportedRange !== null &&
                    "minimum" in details.supportedRange &&
                    "maximum" in details.supportedRange) {
                    const supportedRange = details.supportedRange;
                    if (typeof supportedRange.minimum === "number" && typeof supportedRange.maximum === "number") {
                        lines.push(`  Supported range: ${supportedRange.minimum}-${supportedRange.maximum}`);
                    }
                }
                if (typeof details.noWriteBoundary === "string") {
                    lines.push(`  No-write boundary: ${details.noWriteBoundary}`);
                }
                if (typeof details.noWriteReason === "string") {
                    lines.push(`  No-write reason: ${details.noWriteReason}`);
                }
                if (typeof details.evidenceOnly === "boolean") {
                    lines.push(`  Evidence only: ${details.evidenceOnly ? "yes" : "no"}`);
                }
                if (typeof details.noWriteSeverity === "string") {
                    lines.push(`  No-write severity: ${details.noWriteSeverity}`);
                }
                if (typeof details.nextAction === "string") {
                    lines.push(`  Next action: ${details.nextAction}`);
                }
                if (typeof details.recommendedCommand === "string") {
                    lines.push(`  Recommended command: ${details.recommendedCommand}`);
                }
                if (typeof details.dispositionStatus === "string") {
                    lines.push(`  Disposition status: ${details.dispositionStatus}`);
                }
                if (typeof details.dispositionStoragePath === "string") {
                    lines.push(`  Disposition storage: ${details.dispositionStoragePath}`);
                }
                if (typeof details.replacementTarget === "string") {
                    lines.push(`  Replacement target: ${details.replacementTarget}`);
                }
                if (typeof details.applyEvidenceStatus === "string") {
                    lines.push(`  Apply evidence: ${details.applyEvidenceStatus}`);
                }
                if (typeof details.recommendationLabel === "string") {
                    lines.push(`  Recommendation label: ${details.recommendationLabel}`);
                }
                if (typeof details.recommendationWriteCapable === "boolean") {
                    lines.push(`  Recommendation write capable: ${details.recommendationWriteCapable ? "yes" : "no"}`);
                }
                if (typeof details.recommendationCapability === "string") {
                    lines.push(`  Recommendation capability: ${details.recommendationCapability}`);
                }
                if (typeof details.recommendationArtifactFamily === "string") {
                    lines.push(`  Recommendation artifact family: ${details.recommendationArtifactFamily}`);
                }
                if (typeof details.recommendationMutationPosture === "string") {
                    lines.push(`  Recommendation mutation posture: ${details.recommendationMutationPosture}`);
                }
                if (typeof details.recommendationCoordinationScope === "string") {
                    lines.push(`  Recommendation coordination scope: ${details.recommendationCoordinationScope}`);
                }
                if (typeof details.recommendationFollowUpOnly === "boolean") {
                    lines.push(`  Recommendation follow-up only: ${details.recommendationFollowUpOnly ? "yes" : "no"}`);
                }
                if (typeof details.recommendationBoundary === "string") {
                    lines.push(`  Recommendation boundary: ${details.recommendationBoundary}`);
                }
                if (typeof details.blocking === "boolean") {
                    lines.push(`  Blocking: ${details.blocking ? "yes" : "no"}`);
                }
                if (typeof details.noWriteRequired === "boolean") {
                    lines.push(`  No-write required: ${details.noWriteRequired ? "yes" : "no"}`);
                }
                if (typeof details.blockingReason === "string") {
                    lines.push(`  Blocking reason: ${details.blockingReason}`);
                }
                if (typeof details.advisoryReason === "string") {
                    lines.push(`  Advisory reason: ${details.advisoryReason}`);
                }
            }
        }
    }
    return lines.join("\n");
}
function normalizeValidationFindingPath(input, options) {
    if (options.repositoryRoot !== undefined && isAbsolutePathLike(input)) {
        return (0, paths_1.toRepositoryRelativePath)(options.repositoryRoot, input);
    }
    return (0, paths_1.parseRepositoryRelativePath)(input).normalizedPath;
}
function isAbsolutePathLike(value) {
    return node_path_1.default.isAbsolute(value) || node_path_1.default.win32.isAbsolute(value);
}
