"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.syncTaskDefinitionStatusFromReview = syncTaskDefinitionStatusFromReview;
exports.syncMilestoneOverviewStatusFromReview = syncMilestoneOverviewStatusFromReview;
exports.syncPhaseMetadataStatusesFromReview = syncPhaseMetadataStatusesFromReview;
exports.syncPhaseOverviewStatusFromReview = syncPhaseOverviewStatusFromReview;
exports.inventoryMetadataState = inventoryMetadataState;
exports.renderMetadataSyncResult = renderMetadataSyncResult;
exports.renderMetadataInventoryResult = renderMetadataInventoryResult;
const node_crypto_1 = require("node:crypto");
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const errors_1 = require("../errors");
const mutation_preconditions_1 = require("../filesystem/mutation-preconditions");
const repository_transaction_1 = require("../filesystem/repository-transaction");
const lifecycle_run_context_1 = require("../lifecycle-run-context");
const paths_1 = require("../paths");
const front_matter_utils_1 = require("./front-matter-utils");
const implementation_summary_reconciliation_1 = require("./implementation-summary-reconciliation");
const planning_document_utils_1 = require("./planning-document-utils");
const planning_review_1 = require("./planning-review");
const task_lifecycle_1 = require("./task-lifecycle");
const task_lifecycle_transitions_1 = require("./task-lifecycle-transitions");
const IMPLEMENTATION_SUMMARY_SECTIONS = [
    'Summary',
    'Changed Paths',
    'Acceptance Criteria Results',
    'Validation Performed',
    'Scope Classification',
    'Deviations',
    'Risks and Follow-Ups',
    'Open Questions',
];
const RECONCILIATION_SECTIONS = [
    '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_PATTERNS = [
    /\{\{\s*[A-Za-z0-9_.-]+\s*\}\}/,
    /\bTBD\b/i,
    /\bTODO\b/i,
    /^PLACEHOLDER$/i,
    /^pending$/i,
    /^pending\./i,
];
const INSTRUCTION_PHRASES = [
    'Template notes:',
    'This implementation summary is initialized as the stable execution artifact for the task.',
    'This reconciliation artifact is initialized as a milestone-generation placeholder',
    'Reference the completed task summaries that make up the milestone evidence.',
    'State whether the milestone is reviewed, pending, partial, or blocked.',
    'Restate the milestone goal in review terms, not implementation steps.',
    'Review each milestone criterion against the task summaries.',
    'Note any planned work that remains after the task summaries are reviewed.',
    'Record newly discovered work that emerged during implementation or review.',
    'Move out-of-scope but relevant follow-up into backlog work here.',
    'Summarize the validation evidence and whether it is sufficient.',
    'List any concrete next tasks that remain after reconciliation.',
    'Call out any remaining ambiguity, drift, or review risk.',
    'Close with the overall milestone verdict and any handoff notes.',
];
const HELPER_COVERAGE = [
    { surface: 'metadata update', status: 'helper-backed write' },
    { surface: 'metadata validate-update', status: 'helper-backed read-only validation' },
    { surface: 'metadata sync-status-from-review', status: 'pair-aware explicit transition adapter' },
    { surface: 'metadata inventory', status: 'read-only inspection' },
    { surface: 'task promote', status: 'helper-backed planning mutation' },
    { surface: 'task update', status: 'non-lifecycle metadata only' },
    { surface: 'implementation-summary update', status: 'non-lifecycle metadata only' },
    { surface: 'reconciliation update', status: 'helper-backed planning mutation' },
    { surface: 'prompt update', status: 'helper-backed non-artifact mutation' },
    { surface: 'template update', status: 'helper-backed non-artifact mutation' },
    { surface: 'manifest update', status: 'helper-backed manifest mutation' },
    { surface: 'spec update', status: 'helper-backed spec-registry mutation' },
];
function syncTaskDefinitionStatusFromReview(options) {
    const taskDefinitionPath = resolveTaskDefinitionInput(options.rootPath);
    assertActiveArtifactMatch(taskDefinitionPath, options.activeArtifactPath);
    const taskAbsolutePath = (0, paths_1.resolveRepositoryRelativePath)(options.repositoryRoot, (0, paths_1.parseRepositoryRelativePath)(taskDefinitionPath));
    if (!node_fs_1.default.existsSync(taskAbsolutePath)) {
        throw (0, errors_1.createUsageError)(`Task definition path '${taskDefinitionPath}' does not exist.`, [
            'Pass an existing repository-relative --task-definition path.',
        ]);
    }
    const taskContent = node_fs_1.default.readFileSync(taskAbsolutePath, 'utf8');
    const taskDocument = parseMarkdownDocument(taskDefinitionPath, taskContent);
    assertArtifactType(taskDocument.frontMatterLines, taskDefinitionPath, 'task_definition');
    const taskDirectoryPath = node_path_1.default.dirname(taskDefinitionPath);
    const pairedImplementationSummaryPath = (0, front_matter_utils_1.toRepositoryLikePath)(node_path_1.default.join(taskDirectoryPath, 'implementation-summary.md'));
    const milestoneReconciliationPath = resolveMilestoneReconciliationPath(taskDefinitionPath);
    const implementationSummaryAssessment = assessImplementationSummary(options.repositoryRoot, pairedImplementationSummaryPath, taskDefinitionPath);
    const reconciliationAssessment = assessMilestoneReconciliation(options.repositoryRoot, milestoneReconciliationPath, taskDefinitionPath);
    const milestoneSummaryAssessment = assessMilestoneTaskSummaries(options.repositoryRoot, taskDefinitionPath);
    if (implementationSummaryAssessment.eligible) {
        const taskStatus = readTopLevelField(taskDocument.frontMatterLines, 'status')?.trim() ?? null;
        let transition = null;
        if (taskStatus !== 'completed') {
            const review = (0, implementation_summary_reconciliation_1.reviewImplementationSummary)(options.repositoryRoot, {
                taskDefinitionPath,
            });
            const reviewReceipt = review.reviewReceipt;
            if (reviewReceipt === null || !reviewReceipt.authorizes.includes('close')) {
                throwMetadataSyncRejected(taskDefinitionPath, pairedImplementationSummaryPath, [
                    'Canonical implementation-summary review did not produce a current close-authorizing receipt.',
                    ...review.blockingIssues,
                ]);
            }
            transition = (0, task_lifecycle_transitions_1.applyTaskLifecycleTransitionSync)((0, task_lifecycle_transitions_1.previewTaskCloseSync)({
                repositoryRoot: options.repositoryRoot,
                taskDefinitionPath,
                reviewReceipt,
            }));
        }
        const changed = transition !== null && transition.changedPaths.length > 0;
        return {
            artifactPath: taskDefinitionPath,
            artifactType: 'task_definition',
            taskDefinitionPath,
            pairedImplementationSummaryPath,
            milestoneReconciliationPath,
            source: 'implementation-summary',
            changed,
            writeApplied: changed,
        };
    }
    if (reconciliationAssessment.eligible && milestoneSummaryAssessment.eligible) {
        const nextContent = (0, front_matter_utils_1.applyStatusAndPlanningFieldTransition)(taskContent, {
            status: 'completed',
        });
        const changed = nextContent !== taskContent;
        if (changed) {
            node_fs_1.default.writeFileSync(taskAbsolutePath, nextContent, 'utf8');
        }
        return {
            artifactPath: taskDefinitionPath,
            artifactType: 'task_definition',
            taskDefinitionPath,
            pairedImplementationSummaryPath,
            milestoneReconciliationPath,
            source: 'reconciliation',
            changed,
            writeApplied: changed,
        };
    }
    const findings = [];
    const details = [
        `Task definition: ${taskDefinitionPath}`,
        ...implementationSummaryAssessment.reasons.map((reason) => `Implementation summary: ${reason}`),
        ...reconciliationAssessment.reasons.map((reason) => `Milestone reconciliation: ${reason}`),
        ...milestoneSummaryAssessment.reasons.map((reason) => `Milestone task summaries: ${reason}`),
    ];
    for (const reason of implementationSummaryAssessment.reasons) {
        findings.push({
            code: 'METADATA_SYNC_BLOCKED',
            message: reason,
            severity: 'error',
            path: pairedImplementationSummaryPath,
        });
    }
    for (const reason of reconciliationAssessment.reasons) {
        findings.push({
            code: 'METADATA_SYNC_BLOCKED',
            message: reason,
            severity: 'error',
            path: milestoneReconciliationPath,
        });
    }
    for (const reason of milestoneSummaryAssessment.reasons) {
        findings.push({
            code: 'METADATA_SYNC_BLOCKED',
            message: reason,
            severity: 'error',
            path: milestoneReconciliationPath,
        });
    }
    throw (0, errors_1.createInvalidConfigError)('Metadata sync from review was rejected.', details, findings);
}
function syncMilestoneOverviewStatusFromReview(options) {
    const milestoneOverviewPath = resolveArtifactInput(options.rootPath, 'milestone-overview', 'milestone-overview.md');
    assertActiveArtifactMatch(milestoneOverviewPath, options.activeArtifactPath);
    const milestoneOverviewAbsolutePath = (0, paths_1.resolveRepositoryRelativePath)(options.repositoryRoot, (0, paths_1.parseRepositoryRelativePath)(milestoneOverviewPath));
    if (!node_fs_1.default.existsSync(milestoneOverviewAbsolutePath)) {
        throw (0, errors_1.createUsageError)(`Milestone overview path '${milestoneOverviewPath}' does not exist.`, [
            'Pass an existing repository-relative --milestone-overview path.',
        ]);
    }
    const milestoneOverviewContent = node_fs_1.default.readFileSync(milestoneOverviewAbsolutePath, 'utf8');
    const milestoneOverviewDocument = parseMarkdownDocument(milestoneOverviewPath, milestoneOverviewContent);
    assertArtifactType(milestoneOverviewDocument.frontMatterLines, milestoneOverviewPath, 'milestone_overview');
    const reconciliationPath = (0, front_matter_utils_1.toRepositoryLikePath)(node_path_1.default.join(node_path_1.default.dirname(milestoneOverviewPath), 'reconciliation.md'));
    const reconciliationAssessment = assessMilestoneOverviewReconciliation(options.repositoryRoot, reconciliationPath);
    if (!reconciliationAssessment.eligible) {
        throwMetadataSyncRejected(milestoneOverviewPath, reconciliationPath, reconciliationAssessment.reasons);
    }
    const nextContent = (0, front_matter_utils_1.applyStatusAndPlanningFieldTransition)(milestoneOverviewContent, { status: 'completed' });
    const changed = nextContent !== milestoneOverviewContent;
    if (changed) {
        node_fs_1.default.writeFileSync(milestoneOverviewAbsolutePath, nextContent, 'utf8');
    }
    return {
        artifactPath: milestoneOverviewPath,
        artifactType: 'milestone_overview',
        taskDefinitionPath: null,
        pairedImplementationSummaryPath: null,
        milestoneReconciliationPath: reconciliationPath,
        source: 'reconciliation',
        changed,
        writeApplied: changed,
    };
}
function syncPhaseMetadataStatusesFromReview(options) {
    const phaseOverviewPath = resolveArtifactInput(options.rootPath, 'phase-overview', 'phase-overview.md');
    assertActiveArtifactMatch(phaseOverviewPath, options.activeArtifactPath);
    const metadataPosture = (0, lifecycle_run_context_1.parseLifecycleMetadataPosture)(options.metadataPosture);
    const review = parseImportedPhaseReviewResult(options.phaseReviewResult);
    const dryRun = options.dryRun === true;
    if (review.phaseOverviewPath !== phaseOverviewPath) {
        throwPhaseMetadataSyncFailure({
            code: 'METADATA_SYNC_STALE_REVIEW',
            path: phaseOverviewPath,
            message: 'The imported phase review selects a different phase overview.',
            details: [`Selected phase: ${phaseOverviewPath}`, `Reviewed phase: ${review.phaseOverviewPath}`],
            recovery: 'Rerun phase review for the selected phase, then preview the new result.',
        });
    }
    if (review.metadataPosture !== metadataPosture) {
        throwPhaseMetadataSyncFailure({
            code: 'METADATA_SYNC_UNAUTHORIZED_POSTURE',
            path: phaseOverviewPath,
            message: 'The imported review metadata posture does not match this invocation.',
            details: [`Review posture: ${review.metadataPosture}`, `Invocation posture: ${metadataPosture}`],
            recovery: 'Rerun phase review with the intended posture; do not rewrite the saved review result.',
        });
    }
    if (metadataPosture !== 'sync-on-clean-review') {
        throwPhaseMetadataSyncFailure({
            code: 'METADATA_SYNC_UNAUTHORIZED_POSTURE',
            path: phaseOverviewPath,
            message: 'Phase metadata sync requires sync-on-clean-review posture.',
            details: ['Read-only posture records expected administrative state but never permits this write surface.'],
            recovery: 'Open or rerun the lifecycle with explicit sync-on-clean-review posture, then obtain a fresh phase review.',
        });
    }
    validatePhaseReviewReceipt(review, phaseOverviewPath);
    if (review.blockingIssues.length > 0 || review.phaseReviewReceipt.blockerCount !== 0) {
        throwPhaseMetadataSyncFailure({
            code: 'METADATA_SYNC_REVIEW_BLOCKED',
            path: phaseOverviewPath,
            message: 'Phase metadata sync requires a review with zero blockers.',
            details: [...review.blockingIssues],
            recovery: 'Resolve the phase review blockers and save a fresh complete review before retrying.',
        });
    }
    if (review.reviewMode !== 'evidence' ||
        !review.phaseReviewReceipt.complete ||
        review.phaseReviewReceipt.authorizes.length !== 1) {
        throwPhaseMetadataSyncFailure({
            code: 'METADATA_SYNC_INCOMPLETE_REVIEW',
            path: phaseOverviewPath,
            message: 'The imported phase review is not complete evidence for metadata synchronization.',
            details: [
                `Review mode: ${review.reviewMode}`,
                `Receipt complete: ${review.phaseReviewReceipt.complete ? 'yes' : 'no'}`,
            ],
            recovery: 'Complete every declared milestone reconciliation, rerun phase review, and use that fresh result.',
        });
    }
    const phaseOverviewAbsolutePath = (0, paths_1.resolveRepositoryRelativePath)(options.repositoryRoot, (0, paths_1.parseRepositoryRelativePath)(phaseOverviewPath));
    if (!node_fs_1.default.existsSync(phaseOverviewAbsolutePath)) {
        throw (0, errors_1.createUsageError)(`Phase overview path '${phaseOverviewPath}' does not exist.`, [
            'Pass an existing repository-relative --phase-overview path.',
        ]);
    }
    const phaseOverviewContent = node_fs_1.default.readFileSync(phaseOverviewAbsolutePath, 'utf8');
    const phaseOverviewDocument = parseMarkdownDocument(phaseOverviewPath, phaseOverviewContent);
    assertArtifactType(phaseOverviewDocument.frontMatterLines, phaseOverviewPath, 'phase_overview');
    const expectedTargetPaths = [
        phaseOverviewPath,
        ...(0, planning_document_utils_1.readDeclaredChildSlugs)(phaseOverviewDocument.sections.get('Milestones') ?? '').map((milestoneSlug) => (0, front_matter_utils_1.toRepositoryLikePath)(node_path_1.default.join(node_path_1.default.dirname(phaseOverviewPath), 'milestones', milestoneSlug, 'milestone-overview.md'))),
    ].sort(compareRepositoryPaths);
    const reviewedTargetPaths = review.metadataStatusTransitions
        .map((transition) => transition.artifactPath)
        .sort(compareRepositoryPaths);
    if (new Set(reviewedTargetPaths).size !== reviewedTargetPaths.length ||
        JSON.stringify(reviewedTargetPaths) !== JSON.stringify(expectedTargetPaths)) {
        throwPhaseMetadataSyncFailure({
            code: 'METADATA_SYNC_PARTIAL_TARGET_SET',
            path: phaseOverviewPath,
            message: 'The phase review does not contain the exact current phase-and-milestone target set.',
            details: [
                `Expected targets: ${expectedTargetPaths.join(', ') || '(none)'}`,
                `Reviewed targets: ${reviewedTargetPaths.join(', ') || '(none)'}`,
            ],
            recovery: 'Rerun phase review from the current phase overview; do not add or remove preview targets manually.',
        });
    }
    const reconciliationByMilestone = new Map(review.reconciliationEvidence.map((entry) => [entry.milestoneOverviewPath, entry]));
    const expectedMilestonePaths = expectedTargetPaths.filter((candidate) => candidate !== phaseOverviewPath);
    if (reconciliationByMilestone.size !== expectedMilestonePaths.length ||
        expectedMilestonePaths.some((candidate) => !reconciliationByMilestone.has(candidate))) {
        throwPhaseMetadataSyncFailure({
            code: 'METADATA_SYNC_PARTIAL_TARGET_SET',
            path: phaseOverviewPath,
            message: 'The phase review does not contain one reconciliation record for every selected milestone.',
            details: [`Expected milestone evidence count: ${expectedMilestonePaths.length}`],
            recovery: 'Rerun phase review after every declared milestone has a paired reconciliation.',
        });
    }
    const preconditions = [];
    const writes = [];
    for (const transition of review.metadataStatusTransitions) {
        const parsedPath = (0, paths_1.parseRepositoryRelativePath)(transition.artifactPath);
        const absolutePath = (0, paths_1.resolveRepositoryRelativePath)(options.repositoryRoot, parsedPath);
        if (!node_fs_1.default.existsSync(absolutePath) || !node_fs_1.default.statSync(absolutePath).isFile()) {
            throwPhaseMetadataSyncFailure({
                code: 'METADATA_SYNC_STALE_REVIEW',
                path: transition.artifactPath,
                message: 'A reviewed metadata target is missing or is no longer a regular file.',
                recovery: 'Restore the canonical artifact or rerun phase review after repairing the declared phase topology.',
            });
        }
        const content = node_fs_1.default.readFileSync(absolutePath, 'utf8');
        const document = parseMarkdownDocument(transition.artifactPath, content);
        assertArtifactType(document.frontMatterLines, transition.artifactPath, transition.artifactType);
        const currentRevision = contentRevision(content);
        const currentStatus = readTopLevelField(document.frontMatterLines, 'status')?.trim() ?? null;
        if (currentRevision !== transition.artifactRevision || currentStatus !== transition.oldStatus) {
            throwPhaseMetadataSyncFailure({
                code: 'METADATA_SYNC_STALE_REVIEW',
                path: transition.artifactPath,
                message: 'A reviewed overview changed after phase review.',
                details: [
                    `Expected revision/status: ${transition.artifactRevision} / ${transition.oldStatus ?? '(missing)'}`,
                    `Current revision/status: ${currentRevision} / ${currentStatus ?? '(missing)'}`,
                ],
                recovery: 'Rerun phase review and preview the replacement receipt against current artifact bytes.',
            });
        }
        if (!transition.eligible ||
            transition.newStatus !== 'completed' ||
            !['draft', 'active', 'ready_for_review', 'completed'].includes(currentStatus ?? '')) {
            throwPhaseMetadataSyncFailure({
                code: 'METADATA_SYNC_INELIGIBLE_STATUS',
                path: transition.artifactPath,
                message: 'A reviewed overview status is not eligible for deterministic completion sync.',
                details: [
                    `Observed status: ${currentStatus ?? '(missing)'}`,
                    `Review eligibility: ${transition.eligible ? 'eligible' : 'ineligible'}`,
                ],
                recovery: 'Resolve the lifecycle status explicitly, then rerun phase review; do not coerce an ineligible transition.',
            });
        }
        const target = {
            repositoryRelativePath: parsedPath.normalizedPath,
            runtimePath: absolutePath,
        };
        preconditions.push((0, mutation_preconditions_1.captureDestinationPresencePreconditionSync)(target), (0, mutation_preconditions_1.captureContentRevisionPreconditionSync)(target));
        const nextContent = (0, front_matter_utils_1.applyStatusAndPlanningFieldTransition)(content, { status: 'completed' });
        if (nextContent !== content) {
            writes.push({ path: transition.artifactPath, contents: nextContent });
        }
    }
    for (const milestonePath of expectedMilestonePaths) {
        const evidence = reconciliationByMilestone.get(milestonePath);
        const expectedReconciliationPath = (0, front_matter_utils_1.toRepositoryLikePath)(node_path_1.default.join(node_path_1.default.dirname(milestonePath), 'reconciliation.md'));
        if (evidence.reconciliationPath !== expectedReconciliationPath ||
            evidence.reconciliationRevision === null ||
            !evidence.completedNonPlaceholder) {
            throwPhaseMetadataSyncFailure({
                code: 'METADATA_SYNC_RECONCILIATION_INELIGIBLE',
                path: expectedReconciliationPath,
                message: 'A selected milestone lacks completed non-placeholder reconciliation evidence.',
                recovery: 'Complete and explicitly accept the canonical reconciliation, then rerun phase review.',
            });
        }
        const reconciliationAbsolute = (0, paths_1.resolveRepositoryRelativePath)(options.repositoryRoot, (0, paths_1.parseRepositoryRelativePath)(expectedReconciliationPath));
        if (!node_fs_1.default.existsSync(reconciliationAbsolute) || !node_fs_1.default.statSync(reconciliationAbsolute).isFile()) {
            throwPhaseMetadataSyncFailure({
                code: 'METADATA_SYNC_STALE_REVIEW',
                path: expectedReconciliationPath,
                message: 'A reviewed reconciliation is missing.',
                recovery: 'Restore or complete the reconciliation, then rerun phase review.',
            });
        }
        const reconciliationContent = node_fs_1.default.readFileSync(reconciliationAbsolute, 'utf8');
        const currentRevision = contentRevision(reconciliationContent);
        if (currentRevision !== evidence.reconciliationRevision) {
            throwPhaseMetadataSyncFailure({
                code: 'METADATA_SYNC_STALE_REVIEW',
                path: expectedReconciliationPath,
                message: 'A reviewed reconciliation changed after phase review.',
                details: [`Expected revision: ${evidence.reconciliationRevision}`, `Current revision: ${currentRevision}`],
                recovery: 'Rerun phase review and preview the replacement receipt.',
            });
        }
        const assessment = assessMilestoneOverviewReconciliation(options.repositoryRoot, expectedReconciliationPath);
        if (!assessment.eligible) {
            throwPhaseMetadataSyncFailure({
                code: 'METADATA_SYNC_RECONCILIATION_INELIGIBLE',
                path: expectedReconciliationPath,
                message: 'Current reconciliation evidence is incomplete or contains placeholder content.',
                details: assessment.reasons,
                recovery: 'Repair and accept the reconciliation, then obtain a fresh phase review.',
            });
        }
        preconditions.push((0, mutation_preconditions_1.captureContentRevisionPreconditionSync)({
            repositoryRelativePath: expectedReconciliationPath,
            runtimePath: reconciliationAbsolute,
        }));
    }
    const revisionPreconditions = preconditions.map(mutation_preconditions_1.serializeMutationPrecondition);
    const changedPaths = writes.map((write) => write.path).sort(compareRepositoryPaths);
    const baseResult = {
        artifactPath: phaseOverviewPath,
        artifactType: 'phase_overview',
        taskDefinitionPath: null,
        pairedImplementationSummaryPath: null,
        milestoneReconciliationPath: null,
        source: 'phase-review',
        changed: writes.length > 0,
        reviewId: review.phaseReviewReceipt.reviewId,
        metadataPosture,
        dryRun,
        changedPaths,
        transitions: review.metadataStatusTransitions,
        revisionPreconditions,
    };
    if (dryRun) {
        return {
            ...baseResult,
            writeApplied: false,
            transactionId: null,
            transactionOutcome: 'preview',
        };
    }
    if (writes.length === 0) {
        return {
            ...baseResult,
            writeApplied: false,
            transactionId: null,
            transactionOutcome: 'no-write',
        };
    }
    const transactionId = `metadata-sync-${review.phaseReviewReceipt.reviewId.slice('phase-review-'.length)}`;
    const transaction = (0, repository_transaction_1.executeRepositoryTransactionSync)(options.repositoryRoot, {
        transactionId,
        transactionKind: 'generic',
        writes,
        preconditions,
    });
    if (transaction.outcome !== 'committed') {
        throwPhaseMetadataSyncFailure({
            code: transaction.outcome === 'conflict'
                ? 'METADATA_SYNC_TRANSACTION_CONFLICT'
                : 'METADATA_SYNC_TRANSACTION_INCOMPLETE',
            path: phaseOverviewPath,
            message: transaction.failure ?? 'The phase metadata repository transaction did not commit.',
            details: transaction.conflicts.map((conflict) => `${conflict.path}: expected ${conflict.expectedState}, observed ${conflict.observedState}`),
            recovery: transaction.outcome === 'conflict'
                ? 'Refresh the phase review and dry-run preview before retrying; no metadata target was written.'
                : 'Inspect the recorded repository transaction before any retry; do not assume partial state is safe.',
        });
    }
    return {
        ...baseResult,
        writeApplied: true,
        transactionId: transaction.transactionId,
        transactionOutcome: transaction.outcome,
    };
}
function syncPhaseOverviewStatusFromReview(options) {
    const phaseOverviewPath = resolveArtifactInput(options.rootPath, 'phase-overview', 'phase-overview.md');
    assertActiveArtifactMatch(phaseOverviewPath, options.activeArtifactPath);
    const phaseOverviewAbsolutePath = (0, paths_1.resolveRepositoryRelativePath)(options.repositoryRoot, (0, paths_1.parseRepositoryRelativePath)(phaseOverviewPath));
    if (!node_fs_1.default.existsSync(phaseOverviewAbsolutePath)) {
        throw (0, errors_1.createUsageError)(`Phase overview path '${phaseOverviewPath}' does not exist.`, [
            'Pass an existing repository-relative --phase-overview path.',
        ]);
    }
    const phaseOverviewContent = node_fs_1.default.readFileSync(phaseOverviewAbsolutePath, 'utf8');
    const phaseOverviewDocument = parseMarkdownDocument(phaseOverviewPath, phaseOverviewContent);
    assertArtifactType(phaseOverviewDocument.frontMatterLines, phaseOverviewPath, 'phase_overview');
    const reasons = [];
    for (const milestoneSlug of (0, planning_document_utils_1.readDeclaredChildSlugs)(phaseOverviewDocument.sections.get('Milestones') ?? '')) {
        const reconciliationPath = (0, front_matter_utils_1.toRepositoryLikePath)(node_path_1.default.join(node_path_1.default.dirname(phaseOverviewPath), 'milestones', milestoneSlug, 'reconciliation.md'));
        const assessment = assessMilestoneOverviewReconciliation(options.repositoryRoot, reconciliationPath);
        reasons.push(...assessment.reasons);
    }
    if (reasons.length > 0) {
        throwMetadataSyncRejected(phaseOverviewPath, phaseOverviewPath, reasons);
    }
    const nextContent = (0, front_matter_utils_1.applyStatusAndPlanningFieldTransition)(phaseOverviewContent, { status: 'completed' });
    const changed = nextContent !== phaseOverviewContent;
    if (changed) {
        node_fs_1.default.writeFileSync(phaseOverviewAbsolutePath, nextContent, 'utf8');
    }
    return {
        artifactPath: phaseOverviewPath,
        artifactType: 'phase_overview',
        taskDefinitionPath: null,
        pairedImplementationSummaryPath: null,
        milestoneReconciliationPath: null,
        source: 'phase-reconciliation',
        changed,
        writeApplied: changed,
    };
}
function inventoryMetadataState(options) {
    const inventoryRootInput = options.rootPath ?? '.day-shift/planning';
    const inventoryRootPath = (0, paths_1.resolveRepositoryRelativePath)(options.repositoryRoot, (0, paths_1.parseRepositoryRelativePath)(inventoryRootInput));
    if (!node_fs_1.default.existsSync(inventoryRootPath)) {
        throw (0, errors_1.createUsageError)(`Inventory root path '${inventoryRootInput}' does not exist.`, [
            'Pass an existing repository-relative --root path.',
        ]);
    }
    const taskDefinitionPaths = collectFilesWithName(inventoryRootPath, 'task-definition.md');
    const opportunities = [];
    let implementationSummariesCompleted = 0;
    let reconciliationsCompleted = 0;
    for (const absoluteTaskDefinitionPath of taskDefinitionPaths) {
        const taskDefinitionPath = (0, front_matter_utils_1.toRepositoryLikePath)(node_path_1.default.relative(options.repositoryRoot, absoluteTaskDefinitionPath));
        const taskDirectoryPath = node_path_1.default.dirname(taskDefinitionPath);
        const implementationSummaryPath = (0, front_matter_utils_1.toRepositoryLikePath)(node_path_1.default.join(taskDirectoryPath, 'implementation-summary.md'));
        const milestoneReconciliationPath = resolveMilestoneReconciliationPath(taskDefinitionPath);
        const taskContent = node_fs_1.default.readFileSync(absoluteTaskDefinitionPath, 'utf8');
        const taskDocument = parseMarkdownDocument(taskDefinitionPath, taskContent);
        const taskStatus = readTopLevelField(taskDocument.frontMatterLines, 'status')?.trim() ?? null;
        const summaryAssessment = assessImplementationSummary(options.repositoryRoot, implementationSummaryPath, taskDefinitionPath);
        if (summaryAssessment.eligible) {
            implementationSummariesCompleted += 1;
        }
        const reconciliationAssessment = assessMilestoneReconciliation(options.repositoryRoot, milestoneReconciliationPath, taskDefinitionPath);
        const milestoneSummaryAssessment = assessMilestoneTaskSummaries(options.repositoryRoot, taskDefinitionPath);
        if (reconciliationAssessment.eligible) {
            reconciliationsCompleted += 1;
        }
        if (summaryAssessment.eligible && taskStatus !== 'completed') {
            opportunities.push({
                taskDefinitionPath,
                implementationSummaryPath,
                milestoneReconciliationPath,
                source: 'implementation-summary',
                reason: 'Accepted completed implementation evidence permits explicit task close; readiness authorization is preserved and review alone does not close the task.',
            });
        }
        if (reconciliationAssessment.eligible && milestoneSummaryAssessment.eligible && taskStatus !== 'completed') {
            opportunities.push({
                taskDefinitionPath,
                implementationSummaryPath,
                milestoneReconciliationPath,
                source: 'reconciliation',
                reason: 'Completed milestone reconciliation evidence is present, but the task definition status is still stale.',
            });
        }
    }
    return {
        repositoryRoot: options.repositoryRoot,
        inventoryRoot: (0, front_matter_utils_1.toRepositoryLikePath)(node_path_1.default.relative(options.repositoryRoot, inventoryRootPath) || '.'),
        taskDefinitionsScanned: taskDefinitionPaths.length,
        implementationSummariesCompleted,
        reconciliationsCompleted,
        helperCoverage: HELPER_COVERAGE,
        updateOpportunities: opportunities,
    };
}
function renderMetadataSyncResult(result) {
    const lines = [
        'Metadata sync from review applied.',
        `Artifact: ${result.artifactPath}`,
        `Artifact type: ${result.artifactType}`,
        `Task definition: ${result.taskDefinitionPath ?? '(not selected)'}`,
        `Paired implementation summary: ${result.pairedImplementationSummaryPath ?? '(not selected)'}`,
        `Milestone reconciliation: ${result.milestoneReconciliationPath ?? '(not selected)'}`,
        `Source: ${result.source}`,
        `Changed: ${result.changed ? 'yes' : 'no'}`,
        `Write applied: ${result.writeApplied ? 'yes' : 'no'}`,
    ];
    if ('reviewId' in result) {
        const phaseResult = result;
        lines.push(`Review receipt: ${phaseResult.reviewId}`, `Metadata posture: ${phaseResult.metadataPosture}`, `Transaction outcome: ${phaseResult.transactionOutcome}`, 'Transitions:');
        for (const transition of phaseResult.transitions) {
            lines.push(`- ${transition.artifactPath}: ${transition.oldStatus ?? '(missing)'} -> ${transition.newStatus} (${transition.artifactRevision})`);
        }
    }
    return lines.join('\n');
}
function renderMetadataInventoryResult(result) {
    const lines = [
        'Metadata inventory',
        `Inventory root: ${result.inventoryRoot}`,
        `Task definitions scanned: ${result.taskDefinitionsScanned}`,
        `Completed implementation summaries: ${result.implementationSummariesCompleted}`,
        `Completed reconciliations: ${result.reconciliationsCompleted}`,
        '',
        'Helper coverage:',
    ];
    for (const entry of result.helperCoverage) {
        lines.push(`- ${entry.surface}: ${entry.status}`);
    }
    lines.push('', 'Update opportunities:');
    if (result.updateOpportunities.length === 0) {
        lines.push('- No actionable metadata state detected.');
    }
    else {
        for (const opportunity of result.updateOpportunities) {
            lines.push(`- ${opportunity.taskDefinitionPath}`);
            lines.push(`  source: ${opportunity.source}`);
            lines.push(`  implementation summary: ${opportunity.implementationSummaryPath}`);
            lines.push(`  milestone reconciliation: ${opportunity.milestoneReconciliationPath}`);
            lines.push(`  reason: ${opportunity.reason}`);
        }
    }
    return lines.join('\n');
}
function parseImportedPhaseReviewResult(value) {
    const envelope = requireObject(value, 'Phase review result');
    const candidate = envelope.status === 'ok' &&
        envelope.command === 'phase review' &&
        typeof envelope.data === 'object' &&
        envelope.data !== null
        ? requireObject(envelope.data, 'Phase review result data')
        : envelope;
    if ((candidate.reviewMode !== 'readiness' && candidate.reviewMode !== 'evidence') ||
        typeof candidate.phaseOverviewPath !== 'string' ||
        !Array.isArray(candidate.blockingIssues) ||
        !candidate.blockingIssues.every((entry) => typeof entry === 'string') ||
        !Array.isArray(candidate.metadataStatusTransitions) ||
        !Array.isArray(candidate.reconciliationEvidence) ||
        typeof candidate.phaseReviewReceipt !== 'object' ||
        candidate.phaseReviewReceipt === null) {
        throw (0, errors_1.createUsageError)('--review-result must contain one complete structured phase review result.', [
            'Run phase review with JSON output and pass the saved result without editing it.',
        ]);
    }
    const metadataPosture = (0, lifecycle_run_context_1.parseLifecycleMetadataPosture)(candidate.metadataPosture);
    const transitions = candidate.metadataStatusTransitions.map(parsePhaseMetadataTransition);
    const reconciliationEvidence = candidate.reconciliationEvidence.map(parsePhaseReconciliationEvidence);
    const receipt = parsePhaseReviewReceipt(candidate.phaseReviewReceipt);
    if (receipt.phaseOverviewPath !== candidate.phaseOverviewPath ||
        receipt.metadataPosture !== metadataPosture ||
        receipt.reviewMode !== candidate.reviewMode ||
        receipt.blockerCount !== candidate.blockingIssues.length ||
        JSON.stringify(receipt.metadataStatusTransitions) !== JSON.stringify(transitions) ||
        JSON.stringify(receipt.reconciliationEvidence) !== JSON.stringify(reconciliationEvidence)) {
        throwPhaseMetadataSyncFailure({
            code: 'METADATA_SYNC_STALE_REVIEW',
            path: candidate.phaseOverviewPath,
            message: 'The phase review receipt does not match the surrounding complete review result.',
            recovery: 'Rerun phase review and pass the unmodified JSON result.',
        });
    }
    return {
        reviewMode: candidate.reviewMode,
        metadataPosture,
        phaseOverviewPath: (0, paths_1.parseRepositoryRelativePath)(candidate.phaseOverviewPath).normalizedPath,
        blockingIssues: candidate.blockingIssues,
        metadataStatusTransitions: transitions,
        reconciliationEvidence,
        phaseReviewReceipt: receipt,
    };
}
function parsePhaseMetadataTransition(value) {
    const item = requireObject(value, 'Phase metadata transition');
    if (typeof item.artifactPath !== 'string' ||
        (item.artifactType !== 'phase_overview' && item.artifactType !== 'milestone_overview') ||
        (item.oldStatus !== null && typeof item.oldStatus !== 'string') ||
        item.newStatus !== 'completed' ||
        typeof item.artifactRevision !== 'string' ||
        !/^sha256:[a-f0-9]{64}$/u.test(item.artifactRevision) ||
        typeof item.eligible !== 'boolean' ||
        typeof item.changed !== 'boolean') {
        throw (0, errors_1.createUsageError)('--review-result contains an invalid phase metadata transition.');
    }
    return {
        artifactPath: (0, paths_1.parseRepositoryRelativePath)(item.artifactPath).normalizedPath,
        artifactType: item.artifactType,
        oldStatus: item.oldStatus,
        newStatus: 'completed',
        artifactRevision: item.artifactRevision,
        eligible: item.eligible,
        changed: item.changed,
    };
}
function parsePhaseReconciliationEvidence(value) {
    const item = requireObject(value, 'Phase reconciliation evidence');
    if (typeof item.milestoneOverviewPath !== 'string' ||
        (item.reconciliationPath !== null && typeof item.reconciliationPath !== 'string') ||
        (item.reconciliationRevision !== null &&
            (typeof item.reconciliationRevision !== 'string' ||
                !/^sha256:[a-f0-9]{64}$/u.test(item.reconciliationRevision))) ||
        typeof item.completedNonPlaceholder !== 'boolean') {
        throw (0, errors_1.createUsageError)('--review-result contains invalid phase reconciliation evidence.');
    }
    return {
        milestoneOverviewPath: (0, paths_1.parseRepositoryRelativePath)(item.milestoneOverviewPath).normalizedPath,
        reconciliationPath: item.reconciliationPath === null ? null : (0, paths_1.parseRepositoryRelativePath)(item.reconciliationPath).normalizedPath,
        reconciliationRevision: item.reconciliationRevision,
        completedNonPlaceholder: item.completedNonPlaceholder,
    };
}
function parsePhaseReviewReceipt(value) {
    const item = requireObject(value, 'Phase review receipt');
    if (item.schemaVersion !== 1 ||
        typeof item.reviewId !== 'string' ||
        typeof item.phaseOverviewPath !== 'string' ||
        typeof item.reviewedAt !== 'string' ||
        (item.reviewMode !== 'readiness' && item.reviewMode !== 'evidence') ||
        !Number.isSafeInteger(item.blockerCount) ||
        typeof item.complete !== 'boolean' ||
        !Array.isArray(item.metadataStatusTransitions) ||
        !Array.isArray(item.reconciliationEvidence) ||
        !Array.isArray(item.authorizes) ||
        !item.authorizes.every((entry) => entry === 'metadata-sync-preview')) {
        throw (0, errors_1.createUsageError)('--review-result contains an invalid phase review receipt.');
    }
    const metadataPosture = (0, lifecycle_run_context_1.parseLifecycleMetadataPosture)(item.metadataPosture);
    const authorizes = item.authorizes.length === 1 ? ['metadata-sync-preview'] : [];
    return {
        schemaVersion: 1,
        reviewId: item.reviewId,
        phaseOverviewPath: (0, paths_1.parseRepositoryRelativePath)(item.phaseOverviewPath).normalizedPath,
        metadataPosture,
        reviewedAt: item.reviewedAt,
        reviewMode: item.reviewMode,
        blockerCount: item.blockerCount,
        complete: item.complete,
        metadataStatusTransitions: item.metadataStatusTransitions.map(parsePhaseMetadataTransition),
        reconciliationEvidence: item.reconciliationEvidence.map(parsePhaseReconciliationEvidence),
        authorizes,
    };
}
function validatePhaseReviewReceipt(review, phaseOverviewPath) {
    const { reviewId, ...receiptWithoutId } = review.phaseReviewReceipt;
    const expectedReviewId = (0, planning_review_1.computePhaseReviewReceiptId)(receiptWithoutId);
    if (reviewId !== expectedReviewId) {
        throwPhaseMetadataSyncFailure({
            code: 'METADATA_SYNC_STALE_REVIEW',
            path: phaseOverviewPath,
            message: 'The phase review receipt identity is invalid.',
            details: [`Expected review identity: ${expectedReviewId}`, `Observed: ${reviewId}`],
            recovery: 'Rerun phase review and use its unmodified structured result.',
        });
    }
}
function requireObject(value, label) {
    if (typeof value !== 'object' || value === null || Array.isArray(value)) {
        throw (0, errors_1.createUsageError)(`${label} must be one JSON object.`);
    }
    return value;
}
function throwPhaseMetadataSyncFailure(options) {
    throw (0, errors_1.createInvalidConfigError)(options.message, [
        ...(options.details ?? []),
        `Recovery: ${options.recovery}`,
        'No metadata write was authorized by phase review alone.',
    ], [
        {
            code: options.code,
            message: options.message,
            severity: 'error',
            path: options.path,
            recovery: options.recovery,
            noWriteBoundary: 'The rejected synchronization applies no phase or milestone metadata writes.',
        },
    ]);
}
function contentRevision(content) {
    return `sha256:${(0, node_crypto_1.createHash)('sha256').update(content).digest('hex')}`;
}
function compareRepositoryPaths(left, right) {
    return left.localeCompare(right);
}
function resolveTaskDefinitionInput(rootPath) {
    const inputPath = rootPath ?? '.day-shift/planning';
    const parsed = (0, paths_1.parseRepositoryRelativePath)(inputPath);
    if (parsed.segments[parsed.segments.length - 1] !== 'task-definition.md') {
        throw (0, errors_1.createUsageError)(`Invalid task definition path '${inputPath}'.`, [
            'Expected a repository-relative path ending in task-definition.md.',
        ]);
    }
    return parsed.normalizedPath;
}
function resolveArtifactInput(rootPath, label, fileName) {
    const inputPath = rootPath ?? '.day-shift/planning';
    const parsed = (0, paths_1.parseRepositoryRelativePath)(inputPath);
    if (parsed.segments[parsed.segments.length - 1] !== fileName) {
        throw (0, errors_1.createUsageError)(`Invalid ${label} path '${inputPath}'.`, [
            `Expected a repository-relative path ending in ${fileName}.`,
        ]);
    }
    return parsed.normalizedPath;
}
function assertActiveArtifactMatch(artifactPath, activeArtifactPath) {
    if (activeArtifactPath === undefined || activeArtifactPath.trim() === '') {
        return;
    }
    const activeArtifact = (0, paths_1.parseRepositoryRelativePath)(activeArtifactPath).normalizedPath;
    if (activeArtifact === artifactPath) {
        return;
    }
    throw (0, errors_1.createInvalidConfigError)('Metadata sync from review was rejected.', [
        'Active artifact conflict.',
        `Field '--active-artifact' is '${activeArtifact}'; expected '${artifactPath}'.`,
        'No partial write was applied.',
    ], [
        {
            code: 'METADATA_SYNC_BLOCKED',
            message: 'Active artifact mismatch for metadata sync-status-from-review.',
            severity: 'error',
            path: artifactPath,
        },
    ]);
}
function parseMarkdownDocument(filePath, fileText) {
    const lines = fileText.split(/\r?\n/);
    if (lines[0] !== '---') {
        throw (0, errors_1.createUsageError)(`Artifact '${(0, front_matter_utils_1.toRepositoryLikePath)(filePath)}' is missing YAML front matter.`);
    }
    let closingIndex = -1;
    for (let index = 1; index < lines.length; index += 1) {
        if (lines[index] === '---') {
            closingIndex = index;
            break;
        }
    }
    if (closingIndex === -1) {
        throw (0, errors_1.createUsageError)(`Artifact '${(0, front_matter_utils_1.toRepositoryLikePath)(filePath)}' has malformed YAML front matter.`);
    }
    const contentLines = lines.slice(closingIndex + 1);
    return {
        frontMatterLines: lines.slice(1, closingIndex),
        contentLines,
        sections: parseSections(contentLines),
    };
}
function parseSections(contentLines) {
    const sections = new Map();
    let currentHeading = null;
    let sectionBuffer = [];
    for (const line of contentLines) {
        const headingMatch = line.match(/^##\s+(.+)$/);
        if (headingMatch !== null) {
            if (currentHeading !== null) {
                sections.set(currentHeading, sectionBuffer.join('\n').trim());
            }
            currentHeading = headingMatch[1].trim();
            sectionBuffer = [];
            continue;
        }
        if (currentHeading !== null) {
            sectionBuffer.push(line);
        }
    }
    if (currentHeading !== null) {
        sections.set(currentHeading, sectionBuffer.join('\n').trim());
    }
    return sections;
}
function readTopLevelField(lines, key) {
    for (const line of lines) {
        if (/^\s/.test(line)) {
            continue;
        }
        const match = line.match(/^([A-Za-z0-9_]+):\s*(.*)$/);
        if (match === null) {
            continue;
        }
        if (match[1] === key) {
            return (0, front_matter_utils_1.parseScalar)(match[2]);
        }
    }
    return undefined;
}
function assertArtifactType(frontMatterLines, filePath, expectedArtifactType) {
    const artifactType = readTopLevelField(frontMatterLines, 'artifact_type')?.trim();
    if (artifactType !== expectedArtifactType) {
        throw (0, errors_1.createUsageError)(`Artifact '${filePath}' is not a ${expectedArtifactType} artifact.`, [
            `Expected artifact_type '${expectedArtifactType}', found '${artifactType ?? '(missing)'}'.`,
        ]);
    }
}
function assessImplementationSummary(repositoryRoot, summaryPath, taskDefinitionPath) {
    const absolutePath = node_path_1.default.join(repositoryRoot, summaryPath);
    if (!node_fs_1.default.existsSync(absolutePath)) {
        return {
            eligible: false,
            reasons: [`Paired implementation summary '${summaryPath}' is missing.`],
        };
    }
    const document = parseMarkdownDocument(summaryPath, node_fs_1.default.readFileSync(absolutePath, 'utf8'));
    const reasons = [];
    assertArtifactType(document.frontMatterLines, summaryPath, 'implementation_summary');
    const taskAbsolutePath = node_path_1.default.join(repositoryRoot, taskDefinitionPath);
    if (!node_fs_1.default.existsSync(taskAbsolutePath)) {
        reasons.push(`Paired task definition '${taskDefinitionPath}' is missing.`);
        return { eligible: false, reasons };
    }
    const taskText = node_fs_1.default.readFileSync(taskAbsolutePath, 'utf8');
    const summaryText = node_fs_1.default.readFileSync(absolutePath, 'utf8');
    const pair = (0, task_lifecycle_1.projectTaskLifecyclePair)({
        taskDefinition: taskText,
        implementationSummary: summaryText,
    });
    const implementationStatus = pair.implementationStatus ?? pair.summary?.legacyImplementationStatus;
    const reviewDisposition = pair.reviewDisposition ?? pair.summary?.legacyReviewDisposition;
    if (implementationStatus !== 'completed') {
        reasons.push(`Paired implementation summary '${summaryPath}' does not carry implementation_status: completed.`);
    }
    if (reviewDisposition !== 'accepted' && reviewDisposition !== 'accepted_with_follow_up') {
        reasons.push(`Paired implementation summary '${summaryPath}' does not carry an accepted current review disposition.`);
    }
    reasons.push(...pair.blockingFindings.map((finding) => finding.message));
    for (const sectionName of IMPLEMENTATION_SUMMARY_SECTIONS) {
        const sectionText = document.sections.get(sectionName);
        if (sectionText === undefined) {
            reasons.push(`Paired implementation summary '${summaryPath}' is missing section '${sectionName}'.`);
            continue;
        }
        if (isPlaceholderContent(sectionText)) {
            reasons.push(`Section '${sectionName}' in '${summaryPath}' still contains placeholder content.`);
        }
    }
    if (reasons.length === 0) {
        return {
            eligible: true,
            reasons: [],
        };
    }
    return {
        eligible: false,
        reasons,
    };
}
function assessMilestoneReconciliation(repositoryRoot, reconciliationPath, taskDefinitionPath) {
    const absolutePath = node_path_1.default.join(repositoryRoot, reconciliationPath);
    if (!node_fs_1.default.existsSync(absolutePath)) {
        return {
            eligible: false,
            reasons: [`Milestone reconciliation '${reconciliationPath}' is missing.`],
        };
    }
    const document = parseMarkdownDocument(reconciliationPath, node_fs_1.default.readFileSync(absolutePath, 'utf8'));
    const reasons = [];
    const fileText = [...document.frontMatterLines, ...document.contentLines].join('\n');
    assertArtifactType(document.frontMatterLines, reconciliationPath, 'reconciliation');
    const reconciliationStatus = readTopLevelField(document.frontMatterLines, 'reconciliation_status')?.trim();
    if (reconciliationStatus !== 'completed') {
        reasons.push(`Milestone reconciliation '${reconciliationPath}' does not carry reconciliation_status: completed.`);
    }
    const status = readTopLevelField(document.frontMatterLines, 'status')?.trim();
    if (status !== 'completed') {
        reasons.push(`Milestone reconciliation '${reconciliationPath}' does not carry status: completed.`);
    }
    for (const sectionName of RECONCILIATION_SECTIONS) {
        const sectionText = document.sections.get(sectionName);
        if (sectionText === undefined) {
            reasons.push(`Milestone reconciliation '${reconciliationPath}' is missing section '${sectionName}'.`);
            continue;
        }
        if (isPlaceholderContent(sectionText)) {
            reasons.push(`Section '${sectionName}' in '${reconciliationPath}' still contains placeholder content.`);
        }
    }
    const taskToken = escapeRegExp(taskDefinitionPath);
    const taskSlug = taskDefinitionPath.split('/').slice(-2, -1)[0] ?? '';
    const acceptedPattern = /\baccepted\b/i;
    const taskReferencePattern = new RegExp(`${taskToken}|\\b${escapeRegExp(taskSlug)}\\b`, 'i');
    if (!acceptedPattern.test(fileText) || !taskReferencePattern.test(fileText)) {
        reasons.push(`Milestone reconciliation '${reconciliationPath}' does not explicitly name task '${taskDefinitionPath}' as accepted.`);
    }
    if (reasons.length === 0) {
        return {
            eligible: true,
            reasons: [],
        };
    }
    return {
        eligible: false,
        reasons,
    };
}
function assessMilestoneOverviewReconciliation(repositoryRoot, reconciliationPath) {
    const absolutePath = node_path_1.default.join(repositoryRoot, reconciliationPath);
    if (!node_fs_1.default.existsSync(absolutePath)) {
        return {
            eligible: false,
            reasons: [`Milestone reconciliation '${reconciliationPath}' is missing.`],
        };
    }
    const document = parseMarkdownDocument(reconciliationPath, node_fs_1.default.readFileSync(absolutePath, 'utf8'));
    const reasons = [];
    assertArtifactType(document.frontMatterLines, reconciliationPath, 'reconciliation');
    if (readTopLevelField(document.frontMatterLines, 'reconciliation_status')?.trim() !== 'completed') {
        reasons.push(`Milestone reconciliation '${reconciliationPath}' does not carry reconciliation_status: completed.`);
    }
    if (readTopLevelField(document.frontMatterLines, 'status')?.trim() !== 'completed') {
        reasons.push(`Milestone reconciliation '${reconciliationPath}' does not carry status: completed.`);
    }
    for (const sectionName of RECONCILIATION_SECTIONS) {
        const sectionText = document.sections.get(sectionName);
        if (sectionText === undefined) {
            reasons.push(`Milestone reconciliation '${reconciliationPath}' is missing section '${sectionName}'.`);
            continue;
        }
        if (isPlaceholderContent(sectionText)) {
            reasons.push(`Section '${sectionName}' in '${reconciliationPath}' still contains placeholder content.`);
        }
    }
    return reasons.length === 0 ? { eligible: true, reasons: [] } : { eligible: false, reasons };
}
function throwMetadataSyncRejected(artifactPath, evidencePath, reasons) {
    throw (0, errors_1.createInvalidConfigError)('Metadata sync from review was rejected.', [`Artifact: ${artifactPath}`, ...reasons], reasons.map((reason) => ({
        code: 'METADATA_SYNC_BLOCKED',
        message: reason,
        severity: 'error',
        path: evidencePath,
    })));
}
function assessMilestoneTaskSummaries(repositoryRoot, taskDefinitionPath) {
    const milestoneTasksDirectoryPath = resolveMilestoneTasksDirectoryPath(taskDefinitionPath);
    const absoluteTasksDirectory = node_path_1.default.join(repositoryRoot, milestoneTasksDirectoryPath);
    if (!node_fs_1.default.existsSync(absoluteTasksDirectory)) {
        return {
            eligible: false,
            reasons: [`Milestone tasks directory '${milestoneTasksDirectoryPath}' is missing.`],
        };
    }
    const taskDefinitionPaths = collectFilesWithName(absoluteTasksDirectory, 'task-definition.md')
        .map((absoluteTaskDefinitionPath) => (0, front_matter_utils_1.toRepositoryLikePath)(node_path_1.default.relative(repositoryRoot, absoluteTaskDefinitionPath)))
        .sort((left, right) => left.localeCompare(right));
    if (taskDefinitionPaths.length === 0) {
        return {
            eligible: false,
            reasons: [`Milestone tasks directory '${milestoneTasksDirectoryPath}' has no task definitions.`],
        };
    }
    const reasons = [];
    for (const currentTaskDefinitionPath of taskDefinitionPaths) {
        const summaryPath = (0, front_matter_utils_1.toRepositoryLikePath)(node_path_1.default.join(node_path_1.default.dirname(currentTaskDefinitionPath), 'implementation-summary.md'));
        const summaryAssessment = assessImplementationSummary(repositoryRoot, summaryPath, currentTaskDefinitionPath);
        if (!summaryAssessment.eligible) {
            reasons.push(...summaryAssessment.reasons.map((reason) => `Task '${currentTaskDefinitionPath}' is not complete: ${reason}`));
        }
    }
    if (reasons.length === 0) {
        return {
            eligible: true,
            reasons: [],
        };
    }
    return {
        eligible: false,
        reasons,
    };
}
function isPlaceholderContent(text) {
    const normalized = text.trim();
    if (normalized.length === 0) {
        return true;
    }
    if (PLACEHOLDER_PATTERNS.some((pattern) => pattern.test(normalized))) {
        return true;
    }
    return INSTRUCTION_PHRASES.some((phrase) => normalized.toLowerCase().includes(phrase.toLowerCase()));
}
function collectFilesWithName(rootPath, fileName) {
    const results = [];
    const entries = node_fs_1.default.readdirSync(rootPath, { withFileTypes: true });
    for (const entry of entries) {
        const absolutePath = node_path_1.default.join(rootPath, entry.name);
        if (entry.isDirectory()) {
            results.push(...collectFilesWithName(absolutePath, fileName));
            continue;
        }
        if (entry.isFile() && entry.name === fileName) {
            results.push(absolutePath);
        }
    }
    return results;
}
function resolveMilestoneReconciliationPath(taskDefinitionPath) {
    const normalizedPath = (0, front_matter_utils_1.toRepositoryLikePath)(taskDefinitionPath);
    const marker = '/tasks/';
    const markerIndex = normalizedPath.lastIndexOf(marker);
    if (markerIndex === -1) {
        return '.day-shift/planning/reconciliation.md';
    }
    return `${normalizedPath.slice(0, markerIndex)}/reconciliation.md`;
}
function resolveMilestoneTasksDirectoryPath(taskDefinitionPath) {
    const normalizedPath = (0, front_matter_utils_1.toRepositoryLikePath)(taskDefinitionPath);
    const marker = '/tasks/';
    const markerIndex = normalizedPath.lastIndexOf(marker);
    if (markerIndex === -1) {
        throw (0, errors_1.createUsageError)(`Task definition '${taskDefinitionPath}' is not under a milestone tasks directory.`, [
            "Expected a path containing '/tasks/<task-slug>/task-definition.md'.",
        ]);
    }
    return `${normalizedPath.slice(0, markerIndex)}/tasks`;
}
function escapeRegExp(value) {
    return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
