"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.reviewTaskPlanning = reviewTaskPlanning;
exports.reviewMilestonePlanning = reviewMilestonePlanning;
exports.reviewPhasePlanning = reviewPhasePlanning;
exports.renderTaskPlanningReviewResult = renderTaskPlanningReviewResult;
exports.renderMilestonePlanningReviewResult = renderMilestonePlanningReviewResult;
exports.renderPhasePlanningReviewResult = renderPhasePlanningReviewResult;
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const errors_1 = require("../errors");
const output_1 = require("../output");
const paths_1 = require("../paths");
const implementation_summary_reconciliation_1 = require("./implementation-summary-reconciliation");
const planning_document_utils_1 = require("./planning-document-utils");
const planning_artifact_document_1 = require("./planning-artifact-document");
const planning_heuristics_1 = require("./planning-heuristics");
const authoring_policy_1 = require("./authoring-policy");
const task_readiness_review_1 = require("./task-readiness-review");
const documentation_path_classifier_1 = require("../validation/documentation-path-classifier");
const review_output_contracts_1 = require("./review-output-contracts");
const mode_balance_1 = require("./mode-balance");
const MILESTONE_REQUIRED_SECTIONS = [
    'Purpose',
    'Scope',
    'Tasks',
    'Acceptance Criteria',
    'Dependencies',
    'Risks',
    'Validation Focus',
    'Open Questions',
];
const PHASE_REQUIRED_SECTIONS = [
    'Purpose',
    'Scope',
    'Milestones',
    'Acceptance Criteria',
    'Dependencies',
    'Risks',
    'Validation Focus',
    'Open Questions',
];
const RECONCILIATION_SECTION_NAMES = [
    'Review Status',
    'Milestone Intent',
    'Completed Task Summaries',
    'Acceptance Criteria Review',
    'Planned Work',
    'Discovered Work',
    'Backlog Work',
    'Accepted Residual Work',
    'Validation Review',
    'Follow-Up Tasks',
    'Review Concerns',
    'Final Notes',
];
const PLACEHOLDER_PATTERN = /(\bTBD\b|\bTODO\b|^PLACEHOLDER$|{{\s*[A-Za-z0-9_]+\s*}}|^pending\b)/im;
const PLACEHOLDER_EXACT_VALUES = new Set([
    'Pending.',
    'Pending. This implementation summary is initialized as the stable execution artifact for the task.',
    'None yet.',
    'None yet. Populate this section when implementation begins.',
    'Pending review after implementation.',
    'Not started. Expected scope is limited to this task\'s declared implementation seams.',
    'Residual risk remains until executable behavior and validation evidence are recorded.',
    'Pending. This reconciliation artifact is initialized as the default milestone review rollup path for completed task summaries.',
    '- Pending. Add completed task implementation summaries as milestone execution work finishes.',
    'Pending review after task implementation summaries are available.',
    'Pending review. Evaluate each milestone criterion against the completed task summary evidence under these canonical headings.',
    'None yet. Record out-of-scope follow-up work here if implementation or review surfaces it.',
    'Pending. Summarize targeted CLI validation evidence once milestone tasks complete.',
    'Pending. Add concrete next tasks here only if reconciliation identifies remaining work after review.',
    'Pending milestone review.',
    'Pending milestone review. No completed task implementation summaries are available yet.',
    'Pending milestone review. Evidence has been refreshed, but milestone acceptance still requires explicit human review.',
]);
function reviewTaskPlanning(repositoryRoot, options) {
    const taskDefinitionPath = resolveRepositoryPath(repositoryRoot, options.taskDefinitionPath, 'task-definition');
    const taskDocument = readRequiredDocument(taskDefinitionPath.absolute, taskDefinitionPath.relative, 'task_definition');
    const taskStatus = (0, planning_document_utils_1.readTopLevelField)(taskDocument.frontMatterLines, 'status')?.trim() ?? null;
    const taskReadiness = (0, planning_document_utils_1.readTopLevelField)(taskDocument.frontMatterLines, 'readiness')?.trim() ?? null;
    const implementationSummaryPath = (0, planning_document_utils_1.toRepositoryLikePath)(node_path_1.default.join(node_path_1.default.dirname(taskDefinitionPath.relative), 'implementation-summary.md'));
    const taskReconciliationPath = (0, planning_document_utils_1.toRepositoryLikePath)(node_path_1.default.join(node_path_1.default.dirname(taskDefinitionPath.relative), 'reconciliation.md'));
    const taskReconciliationAbsolute = node_path_1.default.join(repositoryRoot, taskReconciliationPath);
    const taskReconciliationExists = node_fs_1.default.existsSync(taskReconciliationAbsolute);
    const summaryState = readSummaryArtifactState(repositoryRoot, implementationSummaryPath);
    const reviewMode = summaryState !== null && summaryState.substantiveEvidence
        ? 'evidence'
        : taskReconciliationExists
            ? 'evidence'
            : 'readiness';
    const blockingIssues = [];
    const warnings = [];
    const metadataHygieneFollowUps = [];
    const heuristicFindings = (0, planning_heuristics_1.collectPlanningHeuristicFindings)({
        artifactPath: taskDefinitionPath.relative,
        artifactFamily: 'task_definition',
        frontMatterLines: taskDocument.frontMatterLines,
        sections: taskDocument.sections,
        enabledRuleFamilies: ['planning-language', 'decomposition', 'target-path-hygiene', 'dependency-hygiene', 'stale-spec-risk', 'lightweight-promotion-pressure'],
        currentLifecycleEvidence: buildTaskCurrentLifecycleEvidence({
            taskDefinitionPath: taskDefinitionPath.relative,
            taskReadiness,
            summaryState,
            reviewMode,
        }),
    });
    warnings.push(...heuristicFindings.map((finding) => finding.message));
    warnings.push(...(0, authoring_policy_1.formatPlanningAuthoringIssues)((0, authoring_policy_1.auditPlanningArtifactAuthoring)({
        artifactPath: taskDefinitionPath.relative,
        artifactType: 'task_definition',
        markdownText: taskDocument.rawText,
        allowLegacyManualAlias: true,
        allowMissingProvenance: true,
    })));
    if (reviewMode === 'readiness') {
        const readinessResult = (0, task_readiness_review_1.reviewTaskReadiness)(repositoryRoot, { taskDefinitionPath: taskDefinitionPath.relative });
        blockingIssues.push(...readinessResult.missingEvidence, ...readinessResult.dependencyBlockers, ...readinessResult.sequencingIssues);
        warnings.push(...readinessResult.handoffBlockers, ...readinessResult.reviewBoundaryWarnings);
        if (readinessResult.readinessStatus === 'ready to implement' && taskReadiness !== 'ready to implement') {
            metadataHygieneFollowUps.push(`Task definition family 'task_definition' readiness should be 'ready to implement', found '${taskReadiness ?? '(missing)'}'. Recommended command: day-shift task update --task-definition ${taskDefinitionPath.relative} --field readiness="ready to implement".`);
        }
        const recoveryGuidance = buildPlanningRecoveryGuidance({
            artifactPath: taskDefinitionPath.relative,
            reviewKind: 'task',
            blockingIssues,
            warnings,
            metadataHygieneFollowUps,
        });
        const findings = buildPlanningReviewFindings({
            artifactPath: taskDefinitionPath.relative,
            reviewKind: 'task',
            blockingIssues,
            warnings,
            metadataHygieneFollowUps,
        }).concat(heuristicFindings);
        return {
            reviewMode,
            taskDefinitionPath: taskDefinitionPath.relative,
            implementationSummaryPath,
            taskReconciliationPath: taskReconciliationExists ? taskReconciliationPath : null,
            blockingIssues,
            warnings,
            metadataHygieneFollowUps,
            readinessStatus: readinessResult.readinessStatus,
            closeoutEvidenceStatus: null,
            modeBalance: null,
            recoveryGuidance,
            findings,
        };
    }
    const summaryResult = (0, implementation_summary_reconciliation_1.reviewImplementationSummary)(repositoryRoot, {
        taskDefinitionPath: taskDefinitionPath.relative,
    });
    blockingIssues.push(...summaryResult.missingEvidence, ...summaryResult.alignmentIssues);
    warnings.push(...summaryResult.placeholderResidue, ...summaryResult.reviewNotes);
    const parentMilestoneOverviewPath = (0, planning_document_utils_1.readUpstreamField)(taskDocument.frontMatterLines, 'milestone_overview')?.trim() ?? null;
    let modeBalance = null;
    if (parentMilestoneOverviewPath !== null
        && node_fs_1.default.existsSync(node_path_1.default.join(repositoryRoot, parentMilestoneOverviewPath))) {
        modeBalance = (0, mode_balance_1.evaluateMilestoneModeBalance)(repositoryRoot, {
            milestoneOverviewPath: parentMilestoneOverviewPath,
            selectedTaskDefinitionPath: taskDefinitionPath.relative,
        });
        if (modeBalance.optedIn
            && modeBalance.breakoutTaskDefinitionPath === taskDefinitionPath.relative
            && !modeBalance.breakoutSatisfied) {
            modeBalance = (0, mode_balance_1.evaluateMilestoneModeBalance)(repositoryRoot, {
                milestoneOverviewPath: parentMilestoneOverviewPath,
                selectedTaskDefinitionPath: taskDefinitionPath.relative,
                requireBreakoutForCloseout: true,
            });
        }
        blockingIssues.push(...modeBalance.blockingIssues);
    }
    if (summaryResult.implementationStatus === 'completed' &&
        summaryResult.artifactStatus === 'completed' &&
        taskStatus !== 'completed') {
        metadataHygieneFollowUps.push(`Shared status for task definition family 'task_definition' should be 'completed', found '${taskStatus ?? '(missing)'}' at '${taskDefinitionPath.relative}'. Recommended command: day-shift task update --task-definition ${taskDefinitionPath.relative} --field status=completed.`);
    }
    if (summaryResult.implementationStatus === 'completed' &&
        summaryResult.artifactStatus === 'completed' &&
        taskReadiness !== 'completed') {
        metadataHygieneFollowUps.push(`Task-specific readiness for family 'task_definition' should be 'completed', found '${taskReadiness ?? '(missing)'}' at '${taskDefinitionPath.relative}' while paired implementation summary family 'implementation_summary' is completed. Recommended command: day-shift task update --task-definition ${taskDefinitionPath.relative} --field readiness=completed.`);
    }
    if (taskReconciliationExists) {
        const taskReconciliationText = node_fs_1.default.readFileSync(taskReconciliationAbsolute, 'utf8');
        const reconciliationDocument = parseMarkdownDocument(taskReconciliationPath, taskReconciliationText);
        const artifactType = (0, planning_document_utils_1.readTopLevelField)(reconciliationDocument.frontMatterLines, 'artifact_type')?.trim() ?? null;
        if (artifactType !== 'reconciliation') {
            blockingIssues.push(`Task-level reconciliation exception artifact '${taskReconciliationPath}' must use artifact_type 'reconciliation'.`);
        }
        else {
            const reconciliationStatus = (0, planning_document_utils_1.readTopLevelField)(reconciliationDocument.frontMatterLines, 'reconciliation_status')?.trim() ?? null;
            const reconciliationArtifactStatus = (0, planning_document_utils_1.readTopLevelField)(reconciliationDocument.frontMatterLines, 'status')?.trim() ?? null;
            if (documentHasPlaceholderContent(taskReconciliationText)) {
                warnings.push(`Task-level reconciliation exception artifact '${taskReconciliationPath}' still contains placeholder review content.`);
            }
            if (reconciliationStatus === 'completed' && reconciliationArtifactStatus !== 'completed') {
                metadataHygieneFollowUps.push(`Shared status for task-level reconciliation family 'reconciliation' should be 'completed' at '${taskReconciliationPath}' when reconciliation_status is 'completed'. Recommended command: day-shift reconciliation update --reconciliation ${taskReconciliationPath} --field status=completed.`);
            }
        }
    }
    const recoveryGuidance = buildPlanningRecoveryGuidance({
        artifactPath: taskDefinitionPath.relative,
        reviewKind: 'task',
        blockingIssues,
        warnings,
        metadataHygieneFollowUps,
        modeBalanceEvaluations: modeBalance === null ? [] : [modeBalance],
    });
    const findings = buildPlanningReviewFindings({
        artifactPath: taskDefinitionPath.relative,
        reviewKind: 'task',
        blockingIssues,
        warnings,
        metadataHygieneFollowUps,
    }).concat(heuristicFindings);
    return {
        reviewMode,
        taskDefinitionPath: taskDefinitionPath.relative,
        implementationSummaryPath,
        taskReconciliationPath: taskReconciliationExists ? taskReconciliationPath : null,
        blockingIssues,
        warnings,
        metadataHygieneFollowUps,
        readinessStatus: null,
        closeoutEvidenceStatus: summaryResult.closeoutEvidenceStatus,
        modeBalance,
        recoveryGuidance,
        findings,
    };
}
function reviewMilestonePlanning(repositoryRoot, options) {
    const milestoneOverviewPath = resolveRepositoryPath(repositoryRoot, options.milestoneOverviewPath, 'milestone-overview');
    const milestoneDocument = readRequiredDocument(milestoneOverviewPath.absolute, milestoneOverviewPath.relative, 'milestone_overview');
    const milestoneStatus = (0, planning_document_utils_1.readTopLevelField)(milestoneDocument.frontMatterLines, 'status')?.trim() ?? null;
    const reconciliationPath = (0, planning_document_utils_1.toRepositoryLikePath)(node_path_1.default.join(node_path_1.default.dirname(milestoneOverviewPath.relative), 'reconciliation.md'));
    const reconciliationAbsolute = node_path_1.default.join(repositoryRoot, reconciliationPath);
    const reconciliationExists = node_fs_1.default.existsSync(reconciliationAbsolute);
    const taskSummaryPaths = collectTaskSummaryPaths(repositoryRoot, milestoneOverviewPath.relative);
    const declaredTaskSlugs = parseDeclaredChildSlugs(milestoneDocument.sections.get('Tasks'));
    const observedTaskSlugs = collectTaskDirectorySlugs(repositoryRoot, milestoneOverviewPath.relative);
    const completedTaskSummaryPaths = [];
    const incompleteTaskSummaryPaths = [];
    for (const summaryPath of taskSummaryPaths) {
        const summaryState = readSummaryArtifactState(repositoryRoot, summaryPath);
        if (summaryState?.implementationStatus === 'completed') {
            completedTaskSummaryPaths.push(summaryPath);
        }
        else {
            incompleteTaskSummaryPaths.push(summaryPath);
        }
    }
    const reviewMode = completedTaskSummaryPaths.length > 0 || reconciliationExists ? 'evidence' : 'readiness';
    const blockingIssues = [];
    const warnings = [];
    const metadataHygieneFollowUps = [];
    const heuristicFindings = (0, planning_heuristics_1.collectPlanningHeuristicFindings)({
        artifactPath: milestoneOverviewPath.relative,
        artifactFamily: 'milestone_overview',
        frontMatterLines: milestoneDocument.frontMatterLines,
        sections: milestoneDocument.sections,
        enabledRuleFamilies: ['planning-language', 'decomposition', 'stale-spec-risk'],
        currentLifecycleEvidence: buildMilestoneCurrentLifecycleEvidence({
            reconciliationPath: reconciliationExists ? reconciliationPath : null,
            completedTaskSummaryPaths,
            incompleteTaskSummaryPaths,
        }),
    });
    warnings.push(...heuristicFindings.map((finding) => finding.message));
    warnings.push(...(0, authoring_policy_1.formatPlanningAuthoringIssues)((0, authoring_policy_1.auditPlanningArtifactAuthoring)({
        artifactPath: milestoneOverviewPath.relative,
        artifactType: 'milestone_overview',
        markdownText: milestoneDocument.rawText,
        allowLegacyManualAlias: true,
        allowMissingProvenance: true,
    })));
    warnings.push(...(0, authoring_policy_1.formatParentDecompositionIssues)((0, authoring_policy_1.auditParentDecomposition)({
        artifactPath: milestoneOverviewPath.relative,
        markdownText: milestoneDocument.rawText,
        childKind: 'task',
        declaredChildSlugs: declaredTaskSlugs,
    })));
    const modeBalance = (0, mode_balance_1.evaluateMilestoneModeBalance)(repositoryRoot, {
        milestoneOverviewPath: milestoneOverviewPath.relative,
        requireBreakoutForCloseout: reviewMode === 'evidence'
            && declaredTaskSlugs.length > 0
            && completedTaskSummaryPaths.length === declaredTaskSlugs.length,
    });
    if (modeBalance.optedIn) {
        blockingIssues.push(...modeBalance.blockingIssues);
    }
    else {
        blockingIssues.push(...collectContractToRuntimeHandoffIssues({
            repositoryRoot,
            milestoneOverviewPath: milestoneOverviewPath.relative,
            declaredTaskSlugs,
        }), ...collectDocumentationLoopIssues({
            repositoryRoot,
            milestoneOverviewPath: milestoneOverviewPath.relative,
            milestoneDocument,
            declaredTaskSlugs,
        }));
    }
    if (reviewMode === 'readiness') {
        collectReadinessSectionIssues(milestoneDocument, milestoneOverviewPath.relative, MILESTONE_REQUIRED_SECTIONS, blockingIssues);
        collectMilestoneChildDriftIssues({
            milestoneOverviewPath: milestoneOverviewPath.relative,
            milestoneStatus,
            declaredTaskSlugs,
            observedTaskSlugs,
            taskSummaryPaths,
            completedTaskSummaryPaths,
            incompleteTaskSummaryPaths,
            blockingIssues,
            warnings,
        });
        return {
            reviewMode,
            milestoneOverviewPath: milestoneOverviewPath.relative,
            reconciliationPath: reconciliationExists ? reconciliationPath : null,
            completedTaskSummaryPaths,
            incompleteTaskSummaryPaths,
            blockingIssues,
            warnings,
            metadataHygieneFollowUps,
            closureEvidenceStatus: null,
            modeBalance,
            recoveryGuidance: buildPlanningRecoveryGuidance({
                artifactPath: milestoneOverviewPath.relative,
                reviewKind: 'milestone',
                blockingIssues,
                warnings,
                metadataHygieneFollowUps,
                modeBalanceEvaluations: [modeBalance],
            }),
            findings: buildPlanningReviewFindings({
                artifactPath: milestoneOverviewPath.relative,
                reviewKind: 'milestone',
                blockingIssues,
                warnings,
                metadataHygieneFollowUps,
            }).concat(heuristicFindings),
        };
    }
    if (completedTaskSummaryPaths.length === 0) {
        blockingIssues.push('No completed task implementation summaries were found for this milestone.');
    }
    collectMilestoneChildDriftIssues({
        milestoneOverviewPath: milestoneOverviewPath.relative,
        milestoneStatus,
        declaredTaskSlugs,
        observedTaskSlugs,
        taskSummaryPaths,
        completedTaskSummaryPaths,
        incompleteTaskSummaryPaths,
        blockingIssues,
        warnings,
    });
    if (incompleteTaskSummaryPaths.length > 0) {
        warnings.push(...incompleteTaskSummaryPaths.map((summaryPath) => {
            return `Task summary '${summaryPath}' is not complete yet.`;
        }));
    }
    let closureEvidenceStatus = null;
    if (!reconciliationExists) {
        warnings.push(`Milestone reconciliation '${reconciliationPath}' is missing, so milestone review coverage is incomplete.`);
    }
    else {
        const reconciliationResult = (0, implementation_summary_reconciliation_1.reviewReconciliation)(repositoryRoot, {
            milestoneOverviewPath: milestoneOverviewPath.relative,
        });
        closureEvidenceStatus = reconciliationResult.closureEvidenceStatus;
        blockingIssues.push(...reconciliationResult.evidenceGaps, ...reconciliationResult.alignmentIssues);
        warnings.push(...reconciliationResult.placeholderResidue, ...reconciliationResult.reviewConcerns);
        if (reconciliationResult.reconciliationStatus === 'completed' &&
            reconciliationResult.artifactStatus === 'completed' &&
            milestoneStatus !== 'completed') {
            metadataHygieneFollowUps.push(`Shared status for milestone overview family 'milestone_overview' should be 'completed', found '${milestoneStatus ?? '(missing)'}' at '${milestoneOverviewPath.relative}' after completed reconciliation evidence. Recommended command: day-shift milestone update --milestone-overview ${milestoneOverviewPath.relative} --field status=completed.`);
        }
    }
    return {
        reviewMode,
        milestoneOverviewPath: milestoneOverviewPath.relative,
        reconciliationPath: reconciliationExists ? reconciliationPath : null,
        completedTaskSummaryPaths,
        incompleteTaskSummaryPaths,
        blockingIssues,
        warnings,
        metadataHygieneFollowUps,
        closureEvidenceStatus,
        modeBalance,
        recoveryGuidance: buildPlanningRecoveryGuidance({
            artifactPath: milestoneOverviewPath.relative,
            reviewKind: 'milestone',
            blockingIssues,
            warnings,
            metadataHygieneFollowUps,
            modeBalanceEvaluations: [modeBalance],
        }),
        findings: buildPlanningReviewFindings({
            artifactPath: milestoneOverviewPath.relative,
            reviewKind: 'milestone',
            blockingIssues,
            warnings,
            metadataHygieneFollowUps,
        }).concat(heuristicFindings),
    };
}
function reviewPhasePlanning(repositoryRoot, options) {
    const phaseOverviewPath = resolveRepositoryPath(repositoryRoot, options.phaseOverviewPath, 'phase-overview');
    const phaseDocument = readRequiredDocument(phaseOverviewPath.absolute, phaseOverviewPath.relative, 'phase_overview');
    const phaseStatus = (0, planning_document_utils_1.readTopLevelField)(phaseDocument.frontMatterLines, 'status')?.trim() ?? null;
    const milestoneOverviewPaths = collectMilestoneOverviewPaths(repositoryRoot, phaseOverviewPath.relative);
    const declaredMilestoneSlugs = parseDeclaredChildSlugs(phaseDocument.sections.get('Milestones'));
    const observedMilestoneSlugs = milestoneOverviewPaths.map((overviewPath) => node_path_1.default.basename(node_path_1.default.dirname(overviewPath)));
    const milestoneStates = milestoneOverviewPaths.map((overviewPath) => {
        return readMilestoneArtifactState(repositoryRoot, overviewPath);
    });
    const reconciledMilestonePaths = milestoneStates
        .filter((state) => state.reconciliationPath !== null)
        .map((state) => state.overviewPath);
    const reviewMode = reconciledMilestonePaths.length > 0 ? 'evidence' : 'readiness';
    const blockingIssues = [];
    const warnings = [];
    const metadataHygieneFollowUps = [];
    warnings.push(...(0, authoring_policy_1.formatPlanningAuthoringIssues)((0, authoring_policy_1.auditPlanningArtifactAuthoring)({
        artifactPath: phaseOverviewPath.relative,
        artifactType: 'phase_overview',
        markdownText: phaseDocument.rawText,
        allowLegacyManualAlias: true,
        allowMissingProvenance: true,
    })));
    warnings.push(...(0, authoring_policy_1.formatParentDecompositionIssues)((0, authoring_policy_1.auditParentDecomposition)({
        artifactPath: phaseOverviewPath.relative,
        markdownText: phaseDocument.rawText,
        childKind: 'milestone',
        declaredChildSlugs: declaredMilestoneSlugs,
    })));
    const modeBalanceEvaluations = milestoneOverviewPaths.map((milestoneOverviewPath) => {
        return (0, mode_balance_1.evaluateMilestoneModeBalance)(repositoryRoot, {
            milestoneOverviewPath,
            requireBreakoutForCloseout: true,
        });
    });
    if (reviewMode === 'readiness') {
        collectReadinessSectionIssues(phaseDocument, phaseOverviewPath.relative, PHASE_REQUIRED_SECTIONS, blockingIssues);
        collectPhaseChildDriftIssues({
            repositoryRoot,
            phaseOverviewPath: phaseOverviewPath.relative,
            phaseStatus,
            declaredMilestoneSlugs,
            observedMilestoneSlugs,
            milestoneStates,
            blockingIssues,
            warnings,
        });
        for (const milestoneOverviewPath of milestoneOverviewPaths) {
            const milestoneDocument = readRequiredDocument(node_path_1.default.join(repositoryRoot, milestoneOverviewPath), milestoneOverviewPath, 'milestone_overview');
            const modeBalance = modeBalanceEvaluations.find((entry) => {
                return entry.milestoneOverviewPath === milestoneOverviewPath;
            });
            const declaredTaskSlugs = parseDeclaredChildSlugs(milestoneDocument.sections.get('Tasks'));
            const issues = modeBalance.optedIn
                ? modeBalance.blockingIssues
                : [
                    ...collectContractToRuntimeHandoffIssues({
                        repositoryRoot,
                        milestoneOverviewPath,
                        declaredTaskSlugs,
                    }),
                    ...collectDocumentationLoopIssues({
                        repositoryRoot,
                        milestoneOverviewPath,
                        milestoneDocument,
                        declaredTaskSlugs,
                    }),
                ];
            blockingIssues.push(...issues.map((issue) => `${milestoneOverviewPath}: ${issue}`));
        }
        return {
            reviewMode,
            phaseOverviewPath: phaseOverviewPath.relative,
            milestoneOverviewPaths,
            reconciledMilestonePaths,
            blockingIssues,
            warnings,
            metadataHygieneFollowUps,
            modeBalanceEvaluations,
            recoveryGuidance: buildPlanningRecoveryGuidance({
                artifactPath: phaseOverviewPath.relative,
                reviewKind: 'phase',
                blockingIssues,
                warnings,
                metadataHygieneFollowUps,
                modeBalanceEvaluations,
            }),
            findings: buildPlanningReviewFindings({
                artifactPath: phaseOverviewPath.relative,
                reviewKind: 'phase',
                blockingIssues,
                warnings,
                metadataHygieneFollowUps,
            }),
        };
    }
    if (milestoneOverviewPaths.length === 0) {
        blockingIssues.push('No milestone overview artifacts were found beneath this phase.');
    }
    collectPhaseChildDriftIssues({
        repositoryRoot,
        phaseOverviewPath: phaseOverviewPath.relative,
        phaseStatus,
        declaredMilestoneSlugs,
        observedMilestoneSlugs,
        milestoneStates,
        blockingIssues,
        warnings,
    });
    if (reconciledMilestonePaths.length === 0) {
        blockingIssues.push('No milestone reconciliation artifacts were found for this phase.');
    }
    let allReviewedMilestonesCompleted = reconciledMilestonePaths.length > 0;
    for (const milestoneState of milestoneStates) {
        const modeBalance = modeBalanceEvaluations.find((entry) => {
            return entry.milestoneOverviewPath === milestoneState.overviewPath;
        });
        if (modeBalance.optedIn) {
            blockingIssues.push(...modeBalance.blockingIssues.map((issue) => {
                return `${milestoneState.overviewPath}: ${issue}`;
            }));
        }
        if (milestoneState.reconciliationPath === null) {
            warnings.push(`Milestone overview '${milestoneState.overviewPath}' does not have a paired reconciliation artifact yet.`);
            allReviewedMilestonesCompleted = false;
            continue;
        }
        const reconciliationResult = (0, implementation_summary_reconciliation_1.reviewReconciliation)(repositoryRoot, {
            milestoneOverviewPath: milestoneState.overviewPath,
        });
        const milestoneDocument = readRequiredDocument(node_path_1.default.join(repositoryRoot, milestoneState.overviewPath), milestoneState.overviewPath, 'milestone_overview');
        const declaredTaskSlugs = parseDeclaredChildSlugs(milestoneDocument.sections.get('Tasks'));
        if (!modeBalance.optedIn) {
            blockingIssues.push(...collectContractToRuntimeHandoffIssues({
                repositoryRoot,
                milestoneOverviewPath: milestoneState.overviewPath,
                declaredTaskSlugs,
            }).map((issue) => {
                return `${milestoneState.overviewPath}: ${issue}`;
            }), ...collectDocumentationLoopIssues({
                repositoryRoot,
                milestoneOverviewPath: milestoneState.overviewPath,
                milestoneDocument,
                declaredTaskSlugs,
            }).map((issue) => {
                return `${milestoneState.overviewPath}: ${issue}`;
            }));
        }
        if (reconciliationResult.closureEvidenceStatus !== 'sufficient') {
            allReviewedMilestonesCompleted = false;
        }
        blockingIssues.push(...reconciliationResult.evidenceGaps.map((issue) => {
            return `${milestoneState.overviewPath}: ${issue}`;
        }), ...reconciliationResult.alignmentIssues.map((issue) => {
            return `${milestoneState.overviewPath}: ${issue}`;
        }));
        warnings.push(...reconciliationResult.placeholderResidue.map((issue) => {
            return `${milestoneState.overviewPath}: ${issue}`;
        }), ...reconciliationResult.reviewConcerns.map((issue) => {
            return `${milestoneState.overviewPath}: ${issue}`;
        }));
        if (reconciliationResult.reconciliationStatus === 'completed' &&
            reconciliationResult.artifactStatus === 'completed' &&
            milestoneState.status !== 'completed') {
            metadataHygieneFollowUps.push(`Shared status for milestone overview family 'milestone_overview' should be 'completed' at '${milestoneState.overviewPath}' after completed reconciliation evidence. Recommended command: day-shift milestone update --milestone-overview ${milestoneState.overviewPath} --field status=completed.`);
        }
    }
    if (allReviewedMilestonesCompleted && phaseStatus !== 'completed') {
        metadataHygieneFollowUps.push(`Shared status for phase overview family 'phase_overview' should be 'completed', found '${phaseStatus ?? '(missing)'}' at '${phaseOverviewPath.relative}' after completed milestone evidence. Recommended command: day-shift phase update --phase-overview ${phaseOverviewPath.relative} --field status=completed.`);
    }
    return {
        reviewMode,
        phaseOverviewPath: phaseOverviewPath.relative,
        milestoneOverviewPaths,
        reconciledMilestonePaths,
        blockingIssues,
        warnings,
        metadataHygieneFollowUps,
        modeBalanceEvaluations,
        recoveryGuidance: buildPlanningRecoveryGuidance({
            artifactPath: phaseOverviewPath.relative,
            reviewKind: 'phase',
            blockingIssues,
            warnings,
            metadataHygieneFollowUps,
            modeBalanceEvaluations,
        }),
        findings: buildPlanningReviewFindings({
            artifactPath: phaseOverviewPath.relative,
            reviewKind: 'phase',
            blockingIssues,
            warnings,
            metadataHygieneFollowUps,
        }),
    };
}
function renderTaskPlanningReviewResult(result) {
    const lines = [
        (0, output_1.renderTerminalHeading)('Task review', 'title').trimEnd(),
        '',
        (0, output_1.renderTerminalSection)({
            heading: 'Summary',
            fields: [
                { label: 'Task definition', value: result.taskDefinitionPath },
                { label: 'No-write review surface', value: 'yes' },
                { label: 'Review mode', value: result.reviewMode },
                { label: 'Implementation summary', value: result.implementationSummaryPath },
                { label: 'Task reconciliation exception', value: result.taskReconciliationPath ?? '(none)' },
                { label: 'Readiness status', value: result.readinessStatus ?? '(not evaluated in evidence mode)' },
                { label: 'Closeout evidence', value: result.closeoutEvidenceStatus ?? '(not evaluated in readiness mode)' },
            ],
            lines: [(0, output_1.renderTerminalBoundary)({ kind: 'read-only' })],
        }),
        '',
        (0, output_1.renderTerminalSection)({
            heading: 'Review Output Contract',
            lines: (0, review_output_contracts_1.renderReviewOutputContractLines)(),
        }),
        '',
        'Blocking Issues:',
    ];
    appendIssueLines(lines, result.blockingIssues);
    lines.push('', 'Warnings:');
    appendIssueLines(lines, result.warnings);
    lines.push('', 'Metadata-Hygiene Follow-Ups:');
    appendIssueLines(lines, result.metadataHygieneFollowUps);
    lines.push('', 'Recovery Guidance:');
    appendIssueLines(lines, result.recoveryGuidance);
    return lines.join('\n');
}
function renderMilestonePlanningReviewResult(result) {
    const lines = [
        (0, output_1.renderTerminalHeading)('Milestone review', 'title').trimEnd(),
        '',
        (0, output_1.renderTerminalSection)({
            heading: 'Summary',
            fields: [
                { label: 'Milestone overview', value: result.milestoneOverviewPath },
                { label: 'No-write review surface', value: 'yes' },
                { label: 'Review mode', value: result.reviewMode },
                { label: 'Reconciliation', value: result.reconciliationPath ?? '(missing)' },
                { label: 'Closure evidence', value: result.closureEvidenceStatus ?? '(not evaluated in readiness mode)' },
            ],
            lines: [(0, output_1.renderTerminalBoundary)({ kind: 'read-only' })],
        }),
        '',
        (0, output_1.renderTerminalSection)({
            heading: 'Review Output Contract',
            lines: (0, review_output_contracts_1.renderReviewOutputContractLines)(),
        }),
        '',
        'Completed Task Summaries:',
    ];
    appendIssueLines(lines, result.completedTaskSummaryPaths);
    lines.push('', 'Incomplete Task Summaries:');
    appendIssueLines(lines, result.incompleteTaskSummaryPaths);
    lines.push('', 'Blocking Issues:');
    appendIssueLines(lines, result.blockingIssues);
    lines.push('', 'Warnings:');
    appendIssueLines(lines, result.warnings);
    lines.push('', 'Metadata-Hygiene Follow-Ups:');
    appendIssueLines(lines, result.metadataHygieneFollowUps);
    lines.push('', 'Recovery Guidance:');
    appendIssueLines(lines, result.recoveryGuidance);
    return lines.join('\n');
}
function renderPhasePlanningReviewResult(result) {
    const lines = [
        (0, output_1.renderTerminalHeading)('Phase review', 'title').trimEnd(),
        '',
        (0, output_1.renderTerminalSection)({
            heading: 'Summary',
            fields: [
                { label: 'Phase overview', value: result.phaseOverviewPath },
                { label: 'No-write review surface', value: 'yes' },
                { label: 'Review mode', value: result.reviewMode },
            ],
            lines: [(0, output_1.renderTerminalBoundary)({ kind: 'read-only' })],
        }),
        '',
        (0, output_1.renderTerminalSection)({
            heading: 'Review Output Contract',
            lines: (0, review_output_contracts_1.renderReviewOutputContractLines)(),
        }),
        '',
        'Milestone Overviews:',
    ];
    appendIssueLines(lines, result.milestoneOverviewPaths);
    lines.push('', 'Milestones With Reconciliation Evidence:');
    appendIssueLines(lines, result.reconciledMilestonePaths);
    lines.push('', 'Blocking Issues:');
    appendIssueLines(lines, result.blockingIssues);
    lines.push('', 'Warnings:');
    appendIssueLines(lines, result.warnings);
    lines.push('', 'Metadata-Hygiene Follow-Ups:');
    appendIssueLines(lines, result.metadataHygieneFollowUps);
    lines.push('', 'Recovery Guidance:');
    appendIssueLines(lines, result.recoveryGuidance);
    return lines.join('\n');
}
function buildPlanningRecoveryGuidance(options) {
    const guidance = [];
    for (const evaluation of options.modeBalanceEvaluations ?? []) {
        guidance.push(...(0, mode_balance_1.renderDocumentationLoopRecoveryProtocol)(evaluation.recoveryProtocol));
    }
    if (options.blockingIssues.length > 0) {
        guidance.push(`Address the cited blocking findings in '${options.artifactPath}' and its paired evidence before treating this ${options.reviewKind} review as implementation or closeout proof.`);
    }
    if (options.warnings.length > 0) {
        guidance.push('Carry warnings forward as advisory evidence only; they do not authorize lifecycle changes or other writes by implication.');
    }
    if (options.metadataHygieneFollowUps.length > 0) {
        guidance.push(`Apply metadata follow-ups only through an explicit update or sync command for '${options.artifactPath}' after confirming the evidence remains deterministic.`);
    }
    return [...new Set(guidance)];
}
function buildPlanningReviewFindings(options) {
    const reviewPrefix = options.reviewKind.toUpperCase();
    return [
        ...options.blockingIssues.map((message) => ({
            code: `${reviewPrefix}_REVIEW_BLOCKING`,
            message,
            severity: 'error',
            path: options.artifactPath,
        })),
        ...options.warnings.map((message) => ({
            ...(0, output_1.createAdvisoryValidationFinding)({
                code: `${reviewPrefix}_REVIEW_WARNING`,
                message,
                path: options.artifactPath,
                advisoryReason: 'weak-evidence',
                recovery: 'Carry this warning forward as advisory review evidence; do not treat it as permission for lifecycle changes or other writes by implication.',
            }),
        })),
        ...options.metadataHygieneFollowUps.map((message) => ({
            ...(0, output_1.createAdvisoryValidationFinding)({
                code: `${reviewPrefix}_REVIEW_METADATA_FOLLOW_UP`,
                message,
                path: options.artifactPath,
                advisoryReason: 'weak-evidence',
                level: 'informational',
                recovery: 'Apply this metadata follow-up only through an explicit update or sync command after confirming the evidence remains deterministic.',
            }),
        })),
    ];
}
function buildTaskCurrentLifecycleEvidence(options) {
    const evidence = [];
    if (options.reviewMode === 'readiness' && options.taskReadiness === 'ready to implement') {
        evidence.push(`task definition '${options.taskDefinitionPath}' declares readiness 'ready to implement'`);
    }
    if (options.summaryState?.implementationStatus === 'completed' && options.summaryState.artifactStatus === 'completed') {
        evidence.push(`paired implementation summary '${options.summaryState.path}' is completed`);
    }
    else if (options.summaryState?.substantiveEvidence === true) {
        evidence.push(`paired implementation summary '${options.summaryState.path}' contains current execution evidence`);
    }
    return evidence;
}
function buildMilestoneCurrentLifecycleEvidence(options) {
    const evidence = [];
    if (options.completedTaskSummaryPaths.length > 0) {
        evidence.push(`${options.completedTaskSummaryPaths.length} completed task implementation summary artifact(s) are present`);
    }
    if (options.reconciliationPath !== null && options.incompleteTaskSummaryPaths.length === 0) {
        evidence.push(`paired milestone reconciliation '${options.reconciliationPath}' is present for all declared task evidence`);
    }
    return evidence;
}
function readRequiredDocument(absolutePath, relativePath, expectedArtifactType) {
    if (!node_fs_1.default.existsSync(absolutePath)) {
        throw (0, errors_1.createUsageError)(`Artifact not found at '${relativePath}'.`);
    }
    const document = parseMarkdownDocument(relativePath, node_fs_1.default.readFileSync(absolutePath, 'utf8'));
    const artifactType = (0, planning_document_utils_1.readTopLevelField)(document.frontMatterLines, 'artifact_type')?.trim() ?? null;
    if (artifactType !== expectedArtifactType) {
        throw (0, errors_1.createUsageError)(`Artifact '${relativePath}' must use artifact_type: ${expectedArtifactType}.`, [
            `Found: ${artifactType ?? '(missing)'}`,
        ]);
    }
    return document;
}
function resolveRepositoryPath(repositoryRoot, inputPath, label) {
    try {
        if (label === 'phase-overview') {
            return (0, paths_1.resolvePlanningOverviewInputPath)(repositoryRoot, {
                layer: 'phase',
                inputPath,
            });
        }
        if (label === 'milestone-overview') {
            return (0, paths_1.resolvePlanningOverviewInputPath)(repositoryRoot, {
                layer: 'milestone',
                inputPath,
            });
        }
        const parsed = (0, paths_1.parseRepositoryRelativePath)(inputPath);
        return {
            relative: parsed.normalizedPath,
            absolute: node_path_1.default.join(repositoryRoot, parsed.normalizedPath),
        };
    }
    catch (error) {
        throw (0, errors_1.createUsageError)(`Invalid --${label} path '${inputPath}'.`, [
            error instanceof Error ? error.message : String(error),
        ]);
    }
}
function parseMarkdownDocument(filePath, text) {
    const parsed = (0, planning_artifact_document_1.parsePlanningArtifactDocument)(text);
    if (!parsed.hasFrontMatter) {
        if (parsed.diagnostics.some((diagnostic) => diagnostic.code === 'unterminated-front-matter')) {
            throw (0, errors_1.createUsageError)(`Artifact '${filePath}' has malformed YAML front matter.`);
        }
        throw (0, errors_1.createUsageError)(`Artifact '${filePath}' is missing YAML front matter.`);
    }
    const sections = new Map();
    for (const section of parsed.sections) {
        sections.set(section.heading, section.contentText.trim());
    }
    return {
        rawText: text,
        frontMatterLines: parsed.frontMatterLines,
        sections,
    };
}
function trimSectionContent(lines) {
    return lines.join('\n').replace(/^\n+/, '').replace(/\n+$/, '').trim();
}
function collectReadinessSectionIssues(document, filePath, requiredSections, blockingIssues) {
    for (const sectionName of requiredSections) {
        const sectionText = document.sections.get(sectionName);
        if (sectionText === undefined) {
            blockingIssues.push(`Artifact '${filePath}' is missing required section '${sectionName}'.`);
            continue;
        }
        if (isPlaceholderContent(sectionText)) {
            blockingIssues.push(`Section '${sectionName}' in '${filePath}' is still incomplete.`);
        }
    }
    const openQuestionsText = document.sections.get('Open Questions');
    if (openQuestionsText !== undefined && !isResolvedOpenQuestions(openQuestionsText)) {
        blockingIssues.push(`Artifact '${filePath}' still has unresolved open questions.`);
    }
}
function isResolvedOpenQuestions(text) {
    const normalized = text.trim().toLowerCase();
    return (normalized === '- none currently.' ||
        normalized === 'none currently.' ||
        normalized === '- none.' ||
        normalized === 'none.');
}
function collectTaskSummaryPaths(repositoryRoot, milestoneOverviewPath) {
    const milestoneDirectory = node_path_1.default.dirname(node_path_1.default.join(repositoryRoot, milestoneOverviewPath));
    const tasksDirectory = node_path_1.default.join(milestoneDirectory, 'tasks');
    if (!node_fs_1.default.existsSync(tasksDirectory)) {
        return [];
    }
    return node_fs_1.default
        .readdirSync(tasksDirectory, { withFileTypes: true })
        .filter((entry) => entry.isDirectory())
        .map((entry) => node_path_1.default.join(tasksDirectory, entry.name, 'implementation-summary.md'))
        .filter((absolutePath) => node_fs_1.default.existsSync(absolutePath))
        .map((absolutePath) => {
        return (0, planning_document_utils_1.toRepositoryLikePath)(node_path_1.default.relative(repositoryRoot, absolutePath));
    })
        .sort();
}
function collectTaskDirectorySlugs(repositoryRoot, milestoneOverviewPath) {
    const milestoneDirectory = node_path_1.default.dirname(node_path_1.default.join(repositoryRoot, milestoneOverviewPath));
    const tasksDirectory = node_path_1.default.join(milestoneDirectory, 'tasks');
    if (!node_fs_1.default.existsSync(tasksDirectory)) {
        return [];
    }
    return node_fs_1.default
        .readdirSync(tasksDirectory, { withFileTypes: true })
        .filter((entry) => entry.isDirectory())
        .map((entry) => entry.name)
        .sort();
}
function collectTaskDefinitionPathsInDeclaredOrder(repositoryRoot, milestoneOverviewPath, declaredTaskSlugs) {
    const milestoneDirectory = node_path_1.default.dirname(node_path_1.default.join(repositoryRoot, milestoneOverviewPath));
    const tasksDirectory = node_path_1.default.join(milestoneDirectory, 'tasks');
    if (!node_fs_1.default.existsSync(tasksDirectory)) {
        return [];
    }
    const declaredPaths = declaredTaskSlugs
        .map((slug) => node_path_1.default.join(tasksDirectory, slug, 'task-definition.md'))
        .filter((absolutePath) => node_fs_1.default.existsSync(absolutePath));
    if (declaredPaths.length > 0) {
        return declaredPaths.map((absolutePath) => {
            return (0, planning_document_utils_1.toRepositoryLikePath)(node_path_1.default.relative(repositoryRoot, absolutePath));
        });
    }
    return node_fs_1.default
        .readdirSync(tasksDirectory, { withFileTypes: true })
        .filter((entry) => entry.isDirectory())
        .map((entry) => node_path_1.default.join(tasksDirectory, entry.name, 'task-definition.md'))
        .filter((absolutePath) => node_fs_1.default.existsSync(absolutePath))
        .map((absolutePath) => {
        return (0, planning_document_utils_1.toRepositoryLikePath)(node_path_1.default.relative(repositoryRoot, absolutePath));
    })
        .sort();
}
function collectContractToRuntimeHandoffIssues(options) {
    const taskDefinitionPaths = collectTaskDefinitionPathsInDeclaredOrder(options.repositoryRoot, options.milestoneOverviewPath, options.declaredTaskSlugs);
    let contractTaskSeen = false;
    for (const taskDefinitionPath of taskDefinitionPaths) {
        const absolutePath = node_path_1.default.join(options.repositoryRoot, taskDefinitionPath);
        const taskText = node_fs_1.default.readFileSync(absolutePath, 'utf8');
        const taskDocument = parseMarkdownDocument(taskDefinitionPath, taskText);
        const artifactType = (0, planning_document_utils_1.readTopLevelField)(taskDocument.frontMatterLines, 'artifact_type')?.trim() ?? null;
        if (artifactType !== 'task_definition') {
            continue;
        }
        const executionMode = (0, planning_document_utils_1.readTopLevelField)(taskDocument.frontMatterLines, 'execution_mode')?.trim() ?? null;
        if (executionMode === 'contract') {
            contractTaskSeen = true;
            continue;
        }
        if ((executionMode === 'runtime' || executionMode === 'hybrid') && contractTaskSeen) {
            if (!taskReferencesFrozenContractEvidence(taskText)) {
                return [
                    `Runtime handoff task '${taskDefinitionPath}' follows contract work but does not reference frozen contract evidence. Add a repository-relative frozen-contract evidence link before treating this milestone as closeout-ready.`,
                ];
            }
            return [];
        }
    }
    return [];
}
function taskReferencesFrozenContractEvidence(taskText) {
    return /frozen[- ]contract evidence/i.test(taskText) && /\.day-shift\/[^\s`)\]]+/.test(taskText);
}
function collectDocumentationLoopIssues(options) {
    if (!milestoneHasRuntimeAcceptanceCriteria(options.milestoneDocument)) {
        return [];
    }
    const milestoneDirectory = node_path_1.default.dirname(node_path_1.default.join(options.repositoryRoot, options.milestoneOverviewPath));
    const tasksDirectory = node_path_1.default.join(milestoneDirectory, 'tasks');
    const summaryEntries = options.declaredTaskSlugs.map((taskSlug, taskIndex) => {
        return {
            taskSlug,
            taskIndex,
            summaryPath: (0, planning_document_utils_1.toRepositoryLikePath)(node_path_1.default.relative(options.repositoryRoot, node_path_1.default.join(tasksDirectory, taskSlug, 'implementation-summary.md'))),
        };
    });
    let previousDocumentationOnlySummary = null;
    for (const entry of summaryEntries) {
        const summaryPath = entry.summaryPath;
        if (!node_fs_1.default.existsSync(node_path_1.default.join(options.repositoryRoot, summaryPath))) {
            previousDocumentationOnlySummary = null;
            continue;
        }
        const summaryState = readSummaryArtifactState(options.repositoryRoot, summaryPath);
        if (summaryState?.implementationStatus !== 'completed' || summaryState.artifactStatus !== 'completed') {
            previousDocumentationOnlySummary = null;
            continue;
        }
        const summaryText = node_fs_1.default.readFileSync(node_path_1.default.join(options.repositoryRoot, summaryPath), 'utf8');
        const summaryDocument = parseMarkdownDocument(summaryPath, summaryText);
        const changedPaths = extractChangedPathBullets(summaryDocument.sections.get('Changed Paths'));
        const documentationOnly = changedPaths.length > 0 && changedPaths.every((changedPath) => {
            return (0, documentation_path_classifier_1.classifyDocumentationPath)(changedPath).category === 'documentation-only';
        });
        if (!documentationOnly) {
            previousDocumentationOnlySummary = null;
            continue;
        }
        if (previousDocumentationOnlySummary !== null) {
            const issues = [
                `Documentation loop detected: completed summaries '${previousDocumentationOnlySummary}' and '${summaryPath}' changed only documentation-classified paths while milestone runtime acceptance criteria remain pending. The next accepted task must be runtime or hybrid breakout work before more contract refinement is accepted.`,
            ];
            issues.push(...collectBreakoutTaskRequirementIssues({
                repositoryRoot: options.repositoryRoot,
                milestoneOverviewPath: options.milestoneOverviewPath,
                declaredTaskSlugs: options.declaredTaskSlugs,
                previousSummaryPath: previousDocumentationOnlySummary,
                currentSummaryPath: summaryPath,
                nextTaskIndex: entry.taskIndex + 1,
            }));
            return issues;
        }
        previousDocumentationOnlySummary = summaryPath;
    }
    return [];
}
function collectBreakoutTaskRequirementIssues(options) {
    const nextTaskSlug = options.declaredTaskSlugs[options.nextTaskIndex];
    if (nextTaskSlug === undefined) {
        return [
            `Documentation loop breakout required after summaries '${options.previousSummaryPath}' and '${options.currentSummaryPath}', but no following declared task exists. Request a separate runtime or hybrid breakout task with Runtime Delta evidence and frozen contract evidence before accepting more contract refinement.`,
        ];
    }
    const nextTaskPath = (0, planning_document_utils_1.toRepositoryLikePath)(node_path_1.default.relative(options.repositoryRoot, node_path_1.default.join(node_path_1.default.dirname(node_path_1.default.join(options.repositoryRoot, options.milestoneOverviewPath)), 'tasks', nextTaskSlug, 'task-definition.md')));
    if (!node_fs_1.default.existsSync(node_path_1.default.join(options.repositoryRoot, nextTaskPath))) {
        return [
            `Documentation loop breakout task '${nextTaskSlug}' is declared after summaries '${options.previousSummaryPath}' and '${options.currentSummaryPath}', but its task definition is missing. Request a separate runtime or hybrid breakout task with Runtime Delta evidence and frozen contract evidence before accepting more contract refinement.`,
        ];
    }
    const taskText = node_fs_1.default.readFileSync(node_path_1.default.join(options.repositoryRoot, nextTaskPath), 'utf8');
    const taskDocument = parseMarkdownDocument(nextTaskPath, taskText);
    const executionMode = (0, planning_document_utils_1.readTopLevelField)(taskDocument.frontMatterLines, 'execution_mode')?.trim() ?? null;
    const issues = [];
    if (executionMode !== 'runtime' && executionMode !== 'hybrid') {
        issues.push(`Documentation loop breakout task '${nextTaskPath}' must use execution_mode: runtime or execution_mode: hybrid before more contract refinement is accepted.`);
    }
    if (!taskHasCompleteRuntimeDeltaEvidence(taskDocument)) {
        issues.push(`Documentation loop breakout task '${nextTaskPath}' must include complete Runtime Delta evidence before more contract refinement is accepted.`);
    }
    if (!taskReferencesFrozenContractEvidence(taskText)) {
        issues.push(`Documentation loop breakout task '${nextTaskPath}' must reference frozen contract evidence before more contract refinement is accepted.`);
    }
    return issues;
}
function taskHasCompleteRuntimeDeltaEvidence(taskDocument) {
    const runtimeDelta = taskDocument.sections.get('Runtime Delta')?.trim() ?? '';
    if (runtimeDelta.length === 0) {
        return false;
    }
    if (/not applicable|before changing this task|pending:/i.test(runtimeDelta)) {
        return false;
    }
    return /runtime target files/i.test(runtimeDelta) && /verification commands/i.test(runtimeDelta);
}
function collectTaskSummaryPathsInDeclaredOrder(repositoryRoot, milestoneOverviewPath, declaredTaskSlugs) {
    const milestoneDirectory = node_path_1.default.dirname(node_path_1.default.join(repositoryRoot, milestoneOverviewPath));
    const tasksDirectory = node_path_1.default.join(milestoneDirectory, 'tasks');
    if (!node_fs_1.default.existsSync(tasksDirectory)) {
        return [];
    }
    const declaredPaths = declaredTaskSlugs
        .map((slug) => node_path_1.default.join(tasksDirectory, slug, 'implementation-summary.md'))
        .filter((absolutePath) => node_fs_1.default.existsSync(absolutePath));
    if (declaredPaths.length > 0) {
        return declaredPaths.map((absolutePath) => {
            return (0, planning_document_utils_1.toRepositoryLikePath)(node_path_1.default.relative(repositoryRoot, absolutePath));
        });
    }
    return collectTaskSummaryPaths(repositoryRoot, milestoneOverviewPath);
}
function milestoneHasRuntimeAcceptanceCriteria(document) {
    const acceptanceCriteria = document.sections.get('Acceptance Criteria') ?? '';
    return /\bruntime\b|\bRuntime Delta\b|non-documentation code|executable validation/i.test(acceptanceCriteria);
}
function extractChangedPathBullets(sectionText) {
    if (sectionText === undefined) {
        return [];
    }
    return sectionText
        .split(/\r?\n/)
        .map((line) => line.trim().match(/^-\s+`?([^`\s]+)`?/))
        .flatMap((match) => match === null ? [] : [match[1]]);
}
function collectMilestoneOverviewPaths(repositoryRoot, phaseOverviewPath) {
    const phaseDirectory = node_path_1.default.dirname(node_path_1.default.join(repositoryRoot, phaseOverviewPath));
    const milestonesDirectory = node_path_1.default.join(phaseDirectory, 'milestones');
    if (!node_fs_1.default.existsSync(milestonesDirectory)) {
        return [];
    }
    return node_fs_1.default
        .readdirSync(milestonesDirectory, { withFileTypes: true })
        .filter((entry) => entry.isDirectory())
        .flatMap((entry) => {
        const milestoneDirectoryPath = (0, planning_document_utils_1.toRepositoryLikePath)(node_path_1.default.relative(repositoryRoot, node_path_1.default.join(milestonesDirectory, entry.name)));
        const resolution = (0, paths_1.resolvePlanningOverviewPath)(repositoryRoot, {
            layer: 'milestone',
            directoryPath: milestoneDirectoryPath,
        });
        return resolution.selected === null ? [] : [resolution.selected.path];
    })
        .sort();
}
function parseDeclaredChildSlugs(sectionText) {
    if (sectionText === undefined) {
        return [];
    }
    const slugs = [];
    for (const line of sectionText.split(/\r?\n/)) {
        const declaration = (0, planning_document_utils_1.parseDeclaredChildSlugBullet)(line);
        if (declaration !== null) {
            slugs.push(declaration.slug);
        }
    }
    return slugs;
}
function collectMilestoneChildDriftIssues(options) {
    const declared = new Set(options.declaredTaskSlugs);
    const observed = new Set(options.observedTaskSlugs);
    for (const slug of options.declaredTaskSlugs) {
        const taskDirectoryPath = (0, planning_document_utils_1.toRepositoryLikePath)(node_path_1.default.join(node_path_1.default.dirname(options.milestoneOverviewPath), 'tasks', slug));
        const summaryPath = (0, planning_document_utils_1.toRepositoryLikePath)(node_path_1.default.join(taskDirectoryPath, 'implementation-summary.md'));
        if (!observed.has(slug)) {
            options.blockingIssues.push(`Milestone overview '${options.milestoneOverviewPath}' declares task '${slug}' but child task directory '${taskDirectoryPath}' is missing. Recommended command: day-shift task new --milestone-overview ${options.milestoneOverviewPath} --task-slug ${slug}.`);
            continue;
        }
        if (!options.taskSummaryPaths.includes(summaryPath)) {
            options.blockingIssues.push(`Milestone overview '${options.milestoneOverviewPath}' declares task '${slug}' but child implementation summary '${summaryPath}' is missing. Recommended command: day-shift implementation-summary build --task-definition ${taskDirectoryPath}/task-definition.md.`);
        }
    }
    for (const slug of options.observedTaskSlugs) {
        if (!declared.has(slug)) {
            options.warnings.push(`Observed task child '${slug}' under '${options.milestoneOverviewPath}' is not declared in the parent Tasks section. Review the parent overview or move the child artifact before closeout.`);
        }
    }
    if (options.milestoneStatus === 'completed' &&
        (options.blockingIssues.length > 0 || options.incompleteTaskSummaryPaths.length > 0)) {
        options.blockingIssues.push(`Milestone overview '${options.milestoneOverviewPath}' has status 'completed' while declared child task evidence is missing or incomplete. Recommended command: day-shift milestone review --milestone-overview ${options.milestoneOverviewPath}.`);
    }
}
function collectPhaseChildDriftIssues(options) {
    const declared = new Set(options.declaredMilestoneSlugs);
    const observed = new Set(options.observedMilestoneSlugs);
    for (const slug of options.declaredMilestoneSlugs) {
        const milestoneDirectoryPath = (0, planning_document_utils_1.toRepositoryLikePath)(node_path_1.default.join(node_path_1.default.dirname(options.phaseOverviewPath), 'milestones', slug));
        const milestoneResolution = (0, paths_1.resolvePlanningOverviewPath)(options.repositoryRoot, {
            layer: 'milestone',
            directoryPath: milestoneDirectoryPath,
        });
        const milestoneOverviewPath = milestoneResolution.selected?.path
            ?? (0, paths_1.composeCanonicalPlanningOverviewPath)('milestone', milestoneDirectoryPath);
        if (milestoneResolution.status === 'conflict') {
            options.blockingIssues.push(`Phase overview '${options.phaseOverviewPath}' declares milestone '${slug}' but child overview candidates conflict. ${milestoneResolution.message}`);
            continue;
        }
        if (!observed.has(slug)) {
            options.blockingIssues.push(`Phase overview '${options.phaseOverviewPath}' declares milestone '${slug}' but child overview '${milestoneOverviewPath}' is missing. Recommended command: day-shift milestone new --phase-overview ${options.phaseOverviewPath} --milestone-slug ${slug}.`);
        }
    }
    for (const slug of options.observedMilestoneSlugs) {
        if (!declared.has(slug)) {
            options.warnings.push(`Observed milestone child '${slug}' under '${options.phaseOverviewPath}' is not declared in the parent Milestones section. Review the parent overview or move the child artifact before closeout.`);
        }
    }
    const incompleteDeclaredMilestones = options.milestoneStates.filter((state) => {
        const slug = node_path_1.default.basename(node_path_1.default.dirname(state.overviewPath));
        return declared.has(slug) && (state.reconciliationPath === null ||
            state.reconciliationStatus !== 'completed' ||
            state.incompleteTaskSummaryPaths.length > 0);
    });
    if (options.phaseStatus === 'completed' && (options.blockingIssues.length > 0 || incompleteDeclaredMilestones.length > 0)) {
        options.blockingIssues.push(`Phase overview '${options.phaseOverviewPath}' has status 'completed' while declared child milestone evidence is missing or incomplete. Recommended command: day-shift phase review --phase-overview ${options.phaseOverviewPath}.`);
    }
}
function readSummaryArtifactState(repositoryRoot, summaryPath) {
    const absolutePath = node_path_1.default.join(repositoryRoot, summaryPath);
    if (!node_fs_1.default.existsSync(absolutePath)) {
        return null;
    }
    const text = node_fs_1.default.readFileSync(absolutePath, 'utf8');
    const document = parseMarkdownDocument(summaryPath, text);
    return {
        path: summaryPath,
        implementationStatus: (0, planning_document_utils_1.readTopLevelField)(document.frontMatterLines, 'implementation_status')?.trim() ?? null,
        artifactStatus: (0, planning_document_utils_1.readTopLevelField)(document.frontMatterLines, 'status')?.trim() ?? null,
        substantiveEvidence: hasSubstantiveSummaryEvidence(document),
    };
}
function hasSubstantiveSummaryEvidence(document) {
    const changedPaths = document.sections.get('Changed Paths');
    const validation = document.sections.get('Validation Performed');
    const summary = document.sections.get('Summary');
    return !isPlaceholderContent(changedPaths) || !isPlaceholderContent(validation) || !isPlaceholderContent(summary);
}
function readMilestoneArtifactState(repositoryRoot, overviewPath) {
    const overviewDocument = readRequiredDocument(node_path_1.default.join(repositoryRoot, overviewPath), overviewPath, 'milestone_overview');
    const reconciliationPath = (0, planning_document_utils_1.toRepositoryLikePath)(node_path_1.default.join(node_path_1.default.dirname(overviewPath), 'reconciliation.md'));
    const reconciliationAbsolute = node_path_1.default.join(repositoryRoot, reconciliationPath);
    const completedTaskSummaryPaths = [];
    const incompleteTaskSummaryPaths = [];
    for (const summaryPath of collectTaskSummaryPaths(repositoryRoot, overviewPath)) {
        const summaryState = readSummaryArtifactState(repositoryRoot, summaryPath);
        if (summaryState?.implementationStatus === 'completed') {
            completedTaskSummaryPaths.push(summaryPath);
        }
        else {
            incompleteTaskSummaryPaths.push(summaryPath);
        }
    }
    return {
        overviewPath,
        status: (0, planning_document_utils_1.readTopLevelField)(overviewDocument.frontMatterLines, 'status')?.trim() ?? null,
        reconciliationPath: node_fs_1.default.existsSync(reconciliationAbsolute) ? reconciliationPath : null,
        reconciliationStatus: node_fs_1.default.existsSync(reconciliationAbsolute)
            ? ((0, planning_document_utils_1.readTopLevelField)(parseMarkdownDocument(reconciliationPath, node_fs_1.default.readFileSync(reconciliationAbsolute, 'utf8')).frontMatterLines, 'reconciliation_status')?.trim() ?? null)
            : null,
        completedTaskSummaryPaths,
        incompleteTaskSummaryPaths,
    };
}
function isPlaceholderContent(text) {
    if (text === undefined) {
        return true;
    }
    if (text.trim() === '') {
        return true;
    }
    if (PLACEHOLDER_PATTERN.test(text)) {
        return true;
    }
    return PLACEHOLDER_EXACT_VALUES.has(text.trim());
}
function documentHasPlaceholderContent(text) {
    return RECONCILIATION_SECTION_NAMES.some((sectionName) => {
        const document = parseMarkdownDocument('reconciliation.md', text);
        return isPlaceholderContent(document.sections.get(sectionName));
    });
}
function appendIssueLines(lines, issues) {
    if (issues.length === 0) {
        lines.push('- (none)');
        return;
    }
    for (const issue of issues) {
        lines.push(`- ${issue}`);
    }
}
