"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.IMPACT_EVIDENCE_QUALITY_STATES = void 0;
exports.getImpactEvidenceQualityContract = getImpactEvidenceQualityContract;
exports.qualifyImpactEvidence = qualifyImpactEvidence;
exports.IMPACT_EVIDENCE_QUALITY_STATES = [
    "direct",
    "inferred",
    "weak",
    "missing",
    "stale",
    "unreadable",
    "malformed",
    "placeholder",
    "contradictory"
];
function getImpactEvidenceQualityContract() {
    return {
        qualityStates: [...exports.IMPACT_EVIDENCE_QUALITY_STATES],
        directEvidenceBoundary: "Direct evidence is reserved for exact structured matches: artifact paths, declared target paths, implementation-summary changed paths, explicit artifact references, valid upstream links, and exact changed-path associations.",
        inferredEvidenceBoundary: "Inferred evidence is reserved for deterministic local relationships: path-prefix changed-path associations and planning parent-child hierarchy links.",
        weakEvidenceBoundary: "Weak evidence remains advisory contextual evidence and must not be promoted to direct evidence without a structured exact or deterministic local relationship.",
        preservedEvidenceBoundary: "Missing, stale, unreadable, malformed, placeholder, and contradictory evidence remains visible for downstream impact findings instead of being filtered before output construction.",
        sharedFindingCompatibility: "Quality states describe evidence certainty and trace condition only; downstream impact findings map them onto the shared validation finding levels without introducing separate severity tokens.",
        readOnly: true
    };
}
function qualifyImpactEvidence(input) {
    const evidence = [];
    for (const artifact of input.artifactEvidence) {
        appendArtifactReadEvidence(evidence, artifact);
        appendArtifactFamilyEvidence(evidence, artifact);
        for (const metadata of artifact.metadataEvidence) {
            evidence.push(qualifyMetadataEvidence(artifact, metadata));
        }
        for (const specReference of artifact.specReferenceEvidence) {
            evidence.push(qualifySpecReferenceEvidence(artifact, specReference));
        }
        for (const section of artifact.bodySectionEvidence) {
            evidence.push(qualifyBodySectionEvidence(artifact, section));
        }
    }
    if (input.changedPathAssociations !== undefined) {
        for (const changedPathEvidence of input.changedPathAssociations.changedPathEvidence) {
            evidence.push({
                quality: changedPathEvidence.state === "normalized" ? "direct" : "malformed",
                evidenceKind: "changed-path",
                sourceState: changedPathEvidence.state,
                traceContext: {
                    sourceArtifactPath: changedPathEvidence.normalizedPath ?? changedPathEvidence.rawInput,
                    artifactFamily: "unsupported",
                    affectedPath: changedPathEvidence.normalizedPath,
                    changedPath: changedPathEvidence.normalizedPath,
                    relationship: changedPathEvidence.state === "normalized" ? "exact" : "malformed"
                },
                findingBoundary: changedPathEvidence.blocking ? "blocking" : "advisory",
                reason: changedPathEvidence.message
            });
        }
        for (const association of input.changedPathAssociations.associations) {
            evidence.push(qualifyPathAssociationEvidence(association));
        }
    }
    return {
        evidence,
        readOnly: true
    };
}
function appendArtifactReadEvidence(evidence, artifact) {
    if (artifact.readState !== "unreadable") {
        return;
    }
    evidence.push({
        quality: "unreadable",
        evidenceKind: "artifact-read",
        sourceState: "unreadable",
        traceContext: baseTraceContext(artifact, "unreadable", artifact.artifactPath),
        findingBoundary: "blocking",
        reason: artifact.errorMessage ?? `Artifact '${artifact.artifactPath}' could not be read.`
    });
}
function appendArtifactFamilyEvidence(evidence, artifact) {
    const pathFamily = inferArtifactFamilyFromPath(artifact.artifactPath);
    if (pathFamily === null || artifact.artifactType === null) {
        return;
    }
    if (pathFamily === artifact.artifactFamily) {
        return;
    }
    evidence.push({
        quality: "contradictory",
        evidenceKind: "artifact-family",
        sourceState: "contradictory",
        traceContext: baseTraceContext(artifact, "contradictory", artifact.artifactPath),
        findingBoundary: "blocking",
        reason: `Artifact '${artifact.artifactPath}' has artifact_type '${artifact.artifactType}' but its path indicates '${pathFamily}'.`
    });
}
function qualifyMetadataEvidence(artifact, metadata) {
    const affectedPath = metadata.field.startsWith("upstream.") || metadata.field === "artifact_path"
        ? metadata.value
        : undefined;
    const quality = qualityForArtifactState(metadata.state, staleQualityForMetadata(artifact, metadata));
    const relationship = relationshipForQuality(quality, metadata.field.startsWith("upstream.") ? "planning-parent-child" : "exact");
    return {
        quality,
        evidenceKind: "artifact-metadata",
        sourceState: metadata.state,
        traceContext: {
            ...baseTraceContext(artifact, relationship, affectedPath),
            sourceField: metadata.field,
            planningCoordinates: planningCoordinatesForArtifact(artifact),
            parentLink: metadata.field.startsWith("upstream.") ? metadata.value : undefined
        },
        findingBoundary: findingBoundaryForQuality(quality),
        reason: quality === "stale"
            ? `Implementation summary metadata field '${metadata.field}' is stale or incomplete in '${artifact.artifactPath}'.`
            : metadata.message
    };
}
function qualifySpecReferenceEvidence(artifact, specReference) {
    const quality = qualityForArtifactState(specReference.state);
    return {
        quality,
        evidenceKind: "spec-reference",
        sourceState: specReference.state,
        traceContext: {
            ...baseTraceContext(artifact, relationshipForQuality(quality, "exact"), specReference.ref),
            sourceField: "upstream.specs",
            planningCoordinates: planningCoordinatesForArtifact(artifact),
            upstreamSpecReference: specReference.ref
        },
        findingBoundary: findingBoundaryForQuality(quality),
        reason: specReference.message
    };
}
function qualifyBodySectionEvidence(artifact, section) {
    const hasStructuredEvidence = section.extractedPaths.length > 0 || section.declaredChildSlugs.length > 0;
    const quality = section.state === "explicit" && !hasStructuredEvidence
        ? "weak"
        : qualityForArtifactState(section.state);
    const affectedPath = section.extractedPaths[0];
    return {
        quality,
        evidenceKind: "body-section",
        sourceState: section.state,
        traceContext: {
            ...baseTraceContext(artifact, section.declaredChildSlugs.length > 0 ? "planning-parent-child" : relationshipForQuality(quality, "exact"), affectedPath),
            sourceSection: section.sectionName,
            planningCoordinates: planningCoordinatesForArtifact(artifact)
        },
        findingBoundary: findingBoundaryForQuality(quality),
        reason: quality === "weak"
            ? `Impact body section '## ${section.sectionName}' in '${artifact.artifactPath}' is advisory context without structured path or child evidence.`
            : section.message
    };
}
function qualifyPathAssociationEvidence(association) {
    const quality = qualityForAssociationRelationship(association.relationship);
    return {
        quality,
        evidenceKind: "path-association",
        traceContext: {
            sourceArtifactPath: association.sourceArtifactPath,
            artifactFamily: association.artifactFamily,
            affectedPath: association.matchedPath,
            changedPath: association.changedPath,
            matchedPath: association.matchedPath,
            sourceField: association.sourceField,
            sourceSection: association.sourceSection,
            relationship: association.relationship
        },
        findingBoundary: "advisory",
        reason: association.message
    };
}
function qualityForArtifactState(state, override) {
    if (override !== undefined) {
        return override;
    }
    if (state === "explicit") {
        return "direct";
    }
    if (state === "contextual") {
        return "weak";
    }
    return state;
}
function staleQualityForMetadata(artifact, metadata) {
    if (artifact.artifactFamily !== "implementation_summary" || metadata.value === undefined) {
        return undefined;
    }
    if (metadata.field !== "implementation_status" && metadata.field !== "status") {
        return undefined;
    }
    return /^completed?$/.test(metadata.value) ? undefined : "stale";
}
function qualityForAssociationRelationship(relationship) {
    return relationship === "exact" ? "direct" : "inferred";
}
function relationshipForQuality(quality, directRelationship) {
    if (quality === "direct") {
        return directRelationship;
    }
    if (quality === "inferred") {
        return "path-prefix";
    }
    if (quality === "weak") {
        return "contextual";
    }
    return quality;
}
function findingBoundaryForQuality(quality) {
    if (quality === "unreadable" || quality === "malformed" || quality === "contradictory") {
        return "blocking";
    }
    return "advisory";
}
function baseTraceContext(artifact, relationship, affectedPath) {
    return {
        sourceArtifactPath: artifact.artifactPath,
        artifactFamily: artifact.artifactFamily,
        affectedPath,
        relationship
    };
}
function planningCoordinatesForArtifact(artifact) {
    const coordinates = {};
    for (const metadata of artifact.metadataEvidence) {
        if (metadata.value === undefined
            || (metadata.field !== "slice"
                && metadata.field !== "phase"
                && metadata.field !== "milestone"
                && metadata.field !== "task")) {
            continue;
        }
        coordinates[metadata.field] = metadata.value;
    }
    return Object.keys(coordinates).length > 0 ? coordinates : undefined;
}
function inferArtifactFamilyFromPath(artifactPath) {
    if (/^\.day-shift\/specs\/.+\.md$/.test(artifactPath)) {
        return "specification";
    }
    if (/\/tasks\/[^/]+\/task-definition\.md$/.test(artifactPath)) {
        return "task_definition";
    }
    if (/\/tasks\/[^/]+\/implementation-summary\.md$/.test(artifactPath)) {
        return "implementation_summary";
    }
    if (/\/reconciliation\.md$/.test(artifactPath)) {
        return "reconciliation";
    }
    if (/\/milestones\/[^/]+\/overview\.md$/.test(artifactPath)) {
        return "milestone_overview";
    }
    if (/\/phases\/[^/]+\/overview\.md$/.test(artifactPath)) {
        return "phase_overview";
    }
    if (/^\.day-shift\/planning\/[^/]+\/overview\.md$/.test(artifactPath)) {
        return "slice_overview";
    }
    return null;
}
