"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TASK_READINESS_REVIEW_PROTOCOL_VERSION = void 0;
exports.reviewTaskReadiness = reviewTaskReadiness;
exports.inspectTaskReadiness = inspectTaskReadiness;
exports.computeTaskReadinessReviewId = computeTaskReadinessReviewId;
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 paths_1 = require("../paths");
const validation_1 = require("../validation");
const artifact_policy_projection_1 = require("./artifact-policy-projection");
const authoring_policy_1 = require("./authoring-policy");
const execution_profiles_1 = require("./execution-profiles");
const front_matter_utils_1 = require("./front-matter-utils");
const markdown_link_materialization_1 = require("./markdown-link-materialization");
const planning_artifact_document_1 = require("./planning-artifact-document");
const planning_document_utils_1 = require("./planning-document-utils");
const planning_heuristics_1 = require("./planning-heuristics");
const runtime_acceptance_1 = require("./runtime-acceptance");
const scaffold_application_1 = require("./scaffold-application");
const semantic_evidence_1 = require("./semantic-evidence");
const task_contract_revision_adoption_1 = require("./task-contract-revision-adoption");
const task_contract_revision_recovery_1 = require("./task-contract-revision-recovery");
const task_attempts_1 = require("./task-attempts");
const task_cycle_runtime_attribution_1 = require("./task-cycle-runtime-attribution");
const task_lifecycle_1 = require("./task-lifecycle");
const task_lifecycle_timestamps_1 = require("./task-lifecycle-timestamps");
const validation_coverage_1 = require("./validation-coverage");
const validation_input_coverage_1 = require("./validation-input-coverage");
const work_discovery_1 = require("./work-discovery");
exports.TASK_READINESS_REVIEW_PROTOCOL_VERSION = 1;
const REQUIRED_SECTIONS = [
    'Objective',
    'Upstream Context',
    'Implementation Target Paths',
    'Current Behavior',
    'Desired Behavior',
    'Acceptance Criteria',
    'Validation Commands',
    'Rollback / Recovery',
    'Risks',
    'Dependencies',
    'Constraints',
    'Assumptions',
    'Open Questions',
];
const PLACEHOLDER_PATTERN = /(\bTBD\b|\bTODO\b|^PLACEHOLDER$|{{\s*[A-Za-z0-9_]+\s*}}|^pending$)/im;
const LEAKED_TEMPLATE_PHRASES = [
    'Template notes:',
    'Use this section to',
    'List only',
    'Keep only',
    'If there are none, use exactly',
];
const UNRESOLVED_PLACEHOLDER_PATTERN = /{{\s*[A-Za-z0-9_]+\s*}}/g;
const FENCED_CODE_BLOCK_PATTERN = /(^|\n)(```|~~~)[^\n]*\n[\s\S]*?\n\2(?=\n|$)/g;
const INLINE_CODE_SPAN_PATTERN = /`+[^`\n]+`+/g;
function runtimeDeltaEvidenceLabel(kind) {
    switch (kind) {
        case 'target':
            return 'runtime target files';
        case 'behavior':
            return 'expected behavior change';
        case 'validation':
            return 'verification commands with expected evidence';
        case 'rollback':
            return 'rollback path';
    }
}
function reviewTaskReadiness(repositoryRoot, options) {
    const reviewedBy = requireReviewActor(options.reviewedBy);
    const reviewedAt = requireReviewTime(options.reviewedAt);
    const inspection = inspectTaskReadiness(repositoryRoot, {
        taskDefinitionPath: options.taskDefinitionPath,
    });
    const resultWithoutIdentity = {
        ...inspection,
        nextAction: buildReadinessNextAction(inspection, reviewedBy, reviewedAt),
        protocolVersion: exports.TASK_READINESS_REVIEW_PROTOCOL_VERSION,
        reviewedBy,
        reviewedAt,
        readOnly: true,
    };
    return {
        readinessReviewId: computeTaskReadinessReviewId(resultWithoutIdentity),
        ...resultWithoutIdentity,
    };
}
/** Evaluates readiness findings without assigning a review identity. */
function inspectTaskReadiness(repositoryRoot, options) {
    const taskDefinitionPath = resolveTaskDefinitionPath(repositoryRoot, options.taskDefinitionPath);
    if (!node_fs_1.default.existsSync(taskDefinitionPath.absolute)) {
        throw (0, errors_1.createUsageError)(`Task definition not found at '${taskDefinitionPath.relative}'.`, [
            'Pass an existing repository-relative --task-definition path.',
        ]);
    }
    const taskBytes = node_fs_1.default.readFileSync(taskDefinitionPath.absolute);
    const fileText = taskBytes.toString('utf8');
    const taskRevision = (0, node_crypto_1.createHash)('sha256').update(taskBytes).digest('hex');
    const authorizationRevision = (0, task_lifecycle_1.taskReadinessAuthorizationSubjectRevision)(fileText) ?? taskRevision;
    const pairedImplementationSummaryPath = (0, front_matter_utils_1.toRepositoryLikePath)(node_path_1.default.join(node_path_1.default.dirname(taskDefinitionPath.relative), 'implementation-summary.md'));
    const implementationSummaryAbsolutePath = node_path_1.default.join(repositoryRoot, pairedImplementationSummaryPath);
    const implementationSummaryText = node_fs_1.default.existsSync(implementationSummaryAbsolutePath)
        ? node_fs_1.default.readFileSync(implementationSummaryAbsolutePath, 'utf8')
        : null;
    const lifecycleProjection = (0, task_lifecycle_1.projectTaskLifecyclePair)({
        taskDefinition: fileText,
        implementationSummary: implementationSummaryText,
    });
    const authorizationState = projectReadinessAuthorizationState(lifecycleProjection);
    const currentAttemptState = projectReadinessAttemptState(repositoryRoot, taskDefinitionPath.relative, fileText, pairedImplementationSummaryPath, implementationSummaryText, lifecycleProjection);
    const parsedTaskDocument = parseTaskDocument(taskDefinitionPath.relative, fileText);
    const missingEvidence = [];
    const materializationBlockers = [];
    const dependencyBlockers = [];
    const sequencingIssues = [];
    const handoffBlockers = [];
    const reviewBoundaryWarnings = [];
    const authoringIssues = (0, authoring_policy_1.auditPlanningArtifactAuthoring)({
        artifactPath: taskDefinitionPath.relative,
        artifactType: 'task_definition',
        markdownText: fileText,
        allowLegacyManualAlias: true,
        allowMissingProvenance: true,
    });
    missingEvidence.push(...(0, authoring_policy_1.formatPlanningAuthoringIssues)(authoringIssues));
    const readiness = readTopLevelField(parsedTaskDocument.frontMatter.lines, 'readiness');
    if (authorizationState === 'stale') {
        missingEvidence.push(currentAttemptState.state === 'open-baseline-only'
            ? 'Stored readiness authorization is stale after a task contract revision; the open baseline-only attempt must be superseded before fresh authorization.'
            : currentAttemptState.state === 'absent'
                ? 'Stored readiness authorization is stale after a task contract revision and must be replaced from this fresh review before implementation.'
                : 'Stored readiness authorization is stale and the current attempt contains lifecycle evidence that cannot be superseded automatically.');
    }
    else if (authorizationState === 'invalid') {
        missingEvidence.push('Stored readiness authorization is incomplete or invalid and cannot authorize implementation.');
    }
    const policyProjection = (0, artifact_policy_projection_1.projectArtifactPolicy)(fileText);
    const workflowTopology = policyProjection.topology;
    const executionMode = policyProjection.evidenceProfile;
    let runtimeCriterionOwnership = null;
    const executionProfile = readTopLevelField(parsedTaskDocument.frontMatter.lines, 'execution_profile')?.trim() ?? null;
    const materialization = (0, markdown_link_materialization_1.inspectMarkdownLinkMaterialization)({
        repositoryRoot,
        artifactPath: taskDefinitionPath.relative,
    });
    if (materialization.candidateCount > 0) {
        const message = `Task has ${materialization.candidateCount} safely materializable planning link candidate${materialization.candidateCount === 1 ? '' : 's'}; complete link materialization before readiness review or authorization.`;
        materializationBlockers.push(message);
        missingEvidence.push(message);
    }
    if (readiness === undefined || readiness.trim() === '') {
        missingEvidence.push("Front matter field 'readiness' is missing.");
    }
    else if (!isAllowedReadiness(readiness.trim())) {
        missingEvidence.push(`Front matter field 'readiness' uses unsupported value '${readiness.trim()}'.`);
    }
    missingEvidence.push(...policyProjection.blockingFindings.map((finding) => finding.message));
    let executionProfileReadiness = null;
    if (executionProfile !== null) {
        if (!(0, execution_profiles_1.isExecutionProfileId)(executionProfile)) {
            missingEvidence.push(`Front matter field 'execution_profile' uses unsupported value '${executionProfile}'.`);
        }
        else {
            const targetPathEvidence = (0, validation_1.readTaskDeclaredTargetPathEvidence)(taskDefinitionPath.relative, fileText);
            executionProfileReadiness = (0, execution_profiles_1.evaluateExecutionProfileReadiness)(executionProfile, {
                sections: parsedTaskDocument.sections,
                targetPaths: targetPathEvidence.explicitTargetPaths,
            });
            missingEvidence.push(...executionProfileReadiness.blockers.map((blocker) => `Execution profile blocker: ${blocker}`));
        }
    }
    for (const sectionName of REQUIRED_SECTIONS) {
        const sectionText = parsedTaskDocument.sections.get(sectionName);
        if (sectionText === undefined) {
            missingEvidence.push(`Missing required section '${sectionName}'.`);
            continue;
        }
        if (isIncompleteSection(sectionText)) {
            missingEvidence.push(`Section '${sectionName}' is incomplete.`);
        }
    }
    if (executionMode === 'runtime' || executionMode === 'hybrid') {
        const runtimeDelta = (0, semantic_evidence_1.readRuntimeDeltaEvidence)(parsedTaskDocument.sections);
        const runtimeDeltaText = runtimeDelta.sectionText;
        if (runtimeDeltaText === null) {
            missingEvidence.push('Runtime Delta section is required for runtime and hybrid tasks.');
        }
        else if (isIncompleteSection(runtimeDeltaText)) {
            missingEvidence.push('Runtime Delta section is incomplete for runtime or hybrid execution mode.');
        }
        else if (runtimeDelta.missingKinds.length > 0) {
            missingEvidence.push(`Runtime Delta section is missing required evidence: ${runtimeDelta.missingKinds
                .map(runtimeDeltaEvidenceLabel)
                .join(', ')}.`);
        }
    }
    const runtimeBaselinePreconditions = (0, task_cycle_runtime_attribution_1.evaluateTaskRuntimeBaselinePreconditions)({
        artifactPath: taskDefinitionPath.relative,
        frontMatterLines: parsedTaskDocument.frontMatter.lines,
        markdownText: fileText,
        evidenceProfile: executionMode,
    });
    const runtimeBaselinePreconditionMessages = runtimeBaselinePreconditions.findings.map((finding) => finding.message);
    missingEvidence.push(...runtimeBaselinePreconditionMessages);
    if (workflowTopology?.workflowLevel === 'structured') {
        const childInspection = (0, runtime_acceptance_1.inspectRuntimeAcceptance)({
            artifactPath: taskDefinitionPath.relative,
            artifactKind: 'task',
            frontMatterLines: parsedTaskDocument.frontMatter.lines,
            markdownText: fileText,
            requireExplicitForExecutableEvidence: true,
        });
        if (executionMode !== 'runtime' && executionMode !== 'hybrid') {
            missingEvidence.push(...childInspection.issues.map((issue) => `Task runtime acceptance: ${issue}`));
            if (childInspection.metadata === null) {
                missingEvidence.push('Direct Structured tasks must declare a self-contained runtime_acceptance contract.');
            }
            else if (executionMode === 'contract' && childInspection.metadata.required) {
                missingEvidence.push("Task evidence_profile 'contract' contradicts runtime_acceptance.required true.");
            }
        }
    }
    else if (workflowTopology?.workflowLevel === 'governed' && workflowTopology.reconciliationRequired) {
        const milestoneOverviewPath = resolveMilestoneOverviewPath(taskDefinitionPath.relative, repositoryRoot);
        if (milestoneOverviewPath !== null) {
            const parentText = node_fs_1.default.readFileSync(milestoneOverviewPath.absolute, 'utf8');
            const parentFrontMatter = parseFrontMatter(milestoneOverviewPath.relative, parentText);
            const parentInspection = (0, runtime_acceptance_1.inspectRuntimeAcceptance)({
                artifactPath: milestoneOverviewPath.relative,
                artifactKind: 'milestone',
                frontMatterLines: parentFrontMatter.lines,
                markdownText: parentText,
            });
            missingEvidence.push(...parentInspection.issues.map((issue) => `Parent runtime acceptance: ${issue}`));
            const childInspection = (0, runtime_acceptance_1.inspectRuntimeAcceptance)({
                artifactPath: taskDefinitionPath.relative,
                artifactKind: 'task',
                frontMatterLines: parsedTaskDocument.frontMatter.lines,
                markdownText: fileText,
                requireExplicitForExecutableEvidence: false,
            });
            if (executionMode !== 'runtime' && executionMode !== 'hybrid') {
                missingEvidence.push(...childInspection.issues.map((issue) => `Task runtime acceptance: ${issue}`));
            }
            if (parentInspection.metadata !== null && runtimeBaselinePreconditions.findings.length === 0) {
                const declaredTaskSlugs = readDeclaredTaskSlugs(parentText);
                runtimeCriterionOwnership = (0, scaffold_application_1.inspectRuntimeCriterionOwnership)({
                    milestoneMarkdownText: parentText,
                    declaredChildSlugs: declaredTaskSlugs,
                    parentCriterionIds: parentInspection.metadata.required ? parentInspection.metadata.criterionIds : [],
                });
                missingEvidence.push(...runtimeCriterionOwnership.issues);
                const taskSlug = readTopLevelField(parsedTaskDocument.frontMatter.lines, 'task')?.trim() ?? '';
                const assignedCriterionIds = runtimeCriterionOwnership.childOwnership.find((ownership) => ownership.childSlug === taskSlug)?.criterionIds;
                if (runtimeCriterionOwnership.mode === 'decomposed' && assignedCriterionIds === undefined) {
                    missingEvidence.push(`Task '${taskSlug || taskDefinitionPath.relative}' has no reviewed runtime criterion assignment in its parent milestone Scaffold Evidence.`);
                }
                missingEvidence.push(...(0, runtime_acceptance_1.validateTaskRuntimeAcceptance)({
                    parent: assignedCriterionIds === undefined
                        ? parentInspection.metadata
                        : {
                            ...parentInspection.metadata,
                            criterionIds: [...assignedCriterionIds],
                        },
                    child: childInspection.metadata,
                    executionMode,
                    taskMarkdown: fileText,
                }));
            }
            else if (childInspection.metadata !== null && executionMode !== 'runtime' && executionMode !== 'hybrid') {
                missingEvidence.push('Task runtime_acceptance metadata cannot classify acceptance when the parent milestone has no authoritative runtime_acceptance metadata.');
            }
        }
    }
    const openQuestionsText = parsedTaskDocument.sections.get('Open Questions');
    if (openQuestionsText !== undefined && !isOpenQuestionsResolved(openQuestionsText)) {
        missingEvidence.push('Open questions are unresolved.');
    }
    const implementationTargetPathsText = parsedTaskDocument.sections.get('Implementation Target Paths');
    const validationCommandsText = parsedTaskDocument.sections.get('Validation Commands') ?? '';
    const declaredTargetPathEvidence = (0, validation_1.readTaskDeclaredTargetPathEvidence)(taskDefinitionPath.relative, fileText);
    const canonicalLifecycleTargetPaths = declaredTargetPathEvidence.explicitTargetPaths
        .filter((targetPath) => targetPath === taskDefinitionPath.relative || targetPath === pairedImplementationSummaryPath)
        .sort();
    const canonicalLifecycleTargetMessages = canonicalLifecycleTargetPaths.length === 0
        ? []
        : [
            `Implementation Target Paths must not include command-owned canonical lifecycle artifacts: ${canonicalLifecycleTargetPaths.join(', ')}. Task lifecycle commands update the canonical pair independently of implementation scope.`,
        ];
    missingEvidence.push(...canonicalLifecycleTargetMessages);
    const implementationTargetPaths = declaredTargetPathEvidence.explicitTargetPaths.filter((targetPath) => !canonicalLifecycleTargetPaths.includes(targetPath));
    const validationCoverage = (0, validation_coverage_1.inspectTaskValidationCoverage)({
        repositoryRoot,
        taskDefinitionPath: taskDefinitionPath.relative,
        targetPaths: implementationTargetPaths,
        validationCommandsText,
    });
    const validationCoverageBlockingMessages = validationCoverage.findings
        .filter((finding) => finding.severity === 'error')
        .map((finding) => finding.message);
    const validationCoverageWarningMessages = validationCoverage.findings
        .filter((finding) => finding.severity !== 'error')
        .map((finding) => finding.message);
    missingEvidence.push(...validationCoverageBlockingMessages);
    reviewBoundaryWarnings.push(...validationCoverageWarningMessages);
    const validationInputInspection = (0, validation_input_coverage_1.inspectTaskDocumentValidationInputCoverage)({
        repositoryRoot,
        taskDefinitionPath: taskDefinitionPath.relative,
        taskText: fileText,
    });
    const contractImpact = validationInputInspection.contractImpact;
    const validationInputCoverage = validationInputInspection.coverage;
    const validationInputBlockingMessages = validationInputCoverage.issues.map((issue) => issue.message);
    missingEvidence.push(...validationInputBlockingMessages);
    const contractImpactWarningMessages = contractImpact.findings
        .filter((finding) => finding.severity !== 'error')
        .map((finding) => finding.message);
    missingEvidence.push(...contractImpact.blockingIssues);
    reviewBoundaryWarnings.push(...contractImpactWarningMessages);
    const constraintsText = parsedTaskDocument.sections.get('Constraints');
    if (implementationTargetPathsText !== undefined &&
        constraintsText !== undefined &&
        forbidsSharedImplementationOverlap(constraintsText)) {
        const overlappingSiblingPaths = detectLaterImplementationTargetOverlap(repositoryRoot, taskDefinitionPath.relative, implementationTargetPathsText);
        if (overlappingSiblingPaths.length > 0) {
            missingEvidence.push(`Implementation Target Paths overlap with later implementation-owned sibling task surfaces despite the declared no-shared-implementation constraint: ${overlappingSiblingPaths.join(', ')}.`);
        }
    }
    const leakedTemplatePhrases = detectLeakedTemplatePhrases(fileText);
    for (const leakedPhrase of leakedTemplatePhrases) {
        missingEvidence.push(`Leaked template scaffolding detected: '${leakedPhrase}'.`);
    }
    const unresolvedPlaceholders = detectUnresolvedPlaceholders(fileText);
    if (unresolvedPlaceholders.length > 0) {
        missingEvidence.push(`Unresolved template placeholders remain: ${unresolvedPlaceholders.join(', ')}.`);
    }
    const dependenciesText = parsedTaskDocument.sections.get('Dependencies');
    if (dependenciesText !== undefined) {
        const dependencyPaths = extractDependencyPaths(dependenciesText);
        const sequencingContext = resolveSequencingContext(taskDefinitionPath.relative, readTopLevelField(parsedTaskDocument.frontMatter.lines, 'task'));
        for (const dependencyPath of dependencyPaths) {
            let parsedDependencyPath;
            try {
                parsedDependencyPath = (0, paths_1.parseRepositoryRelativePath)(dependencyPath);
            }
            catch {
                dependencyBlockers.push(`Dependency path '${dependencyPath}' is not a valid repository-relative path.`);
                continue;
            }
            if (!isArtifactPathLike(parsedDependencyPath.normalizedPath)) {
                dependencyBlockers.push(`Dependency entry '${dependencyPath}' is prose, not a repository-relative artifact path. Move behavioral dependency prose to Upstream Context, Current Behavior, or Assumptions, or replace it with concrete artifact paths.`);
                continue;
            }
            let resolvedDependencyPath = parsedDependencyPath.normalizedPath;
            const dependencyAbsolutePath = node_path_1.default.join(repositoryRoot, resolvedDependencyPath);
            if (!node_fs_1.default.existsSync(dependencyAbsolutePath)) {
                const mappedDependencyPath = resolveDurablyMappedDependencyPath(repositoryRoot, parsedDependencyPath.normalizedPath);
                if (mappedDependencyPath === null) {
                    dependencyBlockers.push(`Dependency artifact '${parsedDependencyPath.normalizedPath}' does not exist.`);
                    continue;
                }
                resolvedDependencyPath = mappedDependencyPath;
            }
            const lifecycleBlocker = inspectTaskDependencyLifecycle(repositoryRoot, resolvedDependencyPath);
            if (lifecycleBlocker !== null) {
                dependencyBlockers.push(lifecycleBlocker);
            }
            const sequencedIssue = detectLaterSiblingDependency(sequencingContext, resolvedDependencyPath);
            if (sequencedIssue !== null) {
                sequencingIssues.push(sequencedIssue);
            }
        }
    }
    const discovery = (0, work_discovery_1.discoverCanonicalWork)({ repositoryRoot });
    const selectedCandidate = discovery.candidates.find((candidate) => candidate.artifactPath === taskDefinitionPath.relative);
    if (selectedCandidate !== undefined) {
        const orderedMutationBlockers = selectedCandidate.blockers.filter((blocker) => blocker.code.startsWith('duplicate-') ||
            blocker.code.includes('ordered-directory') ||
            blocker.code.includes('root-order') ||
            blocker.code.includes('task-sequence'));
        missingEvidence.push(...orderedMutationBlockers.map((blocker) => `Ordered-directory mutation precondition failed: ${blocker.message}`));
    }
    const readinessStatus = missingEvidence.length === 0 && dependencyBlockers.length === 0 && sequencingIssues.length === 0
        ? 'ready to implement'
        : 'blocked';
    const milestoneReconciliationPath = workflowTopology?.reconciliationRequired === true
        ? resolveMilestoneReconciliationPath(taskDefinitionPath.relative)
        : null;
    if (implementationSummaryText === null) {
        handoffBlockers.push(`Paired implementation summary '${pairedImplementationSummaryPath}' does not exist.`);
    }
    else {
        const summaryProjection = (0, task_lifecycle_1.projectImplementationSummaryLifecycle)(implementationSummaryText);
        handoffBlockers.push(...summaryProjection.blockingFindings.map((finding) => finding.message));
    }
    const reconciliationAbsolutePath = milestoneReconciliationPath === null ? null : node_path_1.default.join(repositoryRoot, milestoneReconciliationPath);
    if (reconciliationAbsolutePath !== null && !node_fs_1.default.existsSync(reconciliationAbsolutePath)) {
        reviewBoundaryWarnings.push(`Milestone reconciliation artifact '${milestoneReconciliationPath}' is missing; milestone-level reconciliation is the default review rollup path.`);
    }
    const handoffStatus = readinessStatus === 'ready to implement' && handoffBlockers.length === 0
        ? 'ready for implementation handoff'
        : 'blocked';
    const currentLifecycleEvidence = handoffStatus === 'ready for implementation handoff'
        ? [
            `task readiness review found '${taskDefinitionPath.relative}' ready for implementation handoff`,
            `paired implementation summary exists at '${pairedImplementationSummaryPath}'`,
        ]
        : [];
    const heuristicFindings = (0, planning_heuristics_1.collectPlanningHeuristicFindings)({
        artifactPath: taskDefinitionPath.relative,
        artifactFamily: 'task_definition',
        frontMatterLines: parsedTaskDocument.frontMatter.lines,
        sections: parsedTaskDocument.sections,
        enabledRuleFamilies: [
            'planning-language',
            'decomposition',
            'target-path-hygiene',
            'dependency-hygiene',
            'stale-spec-risk',
            'lightweight-promotion-pressure',
        ],
        currentLifecycleEvidence,
    });
    reviewBoundaryWarnings.push(...heuristicFindings.map((finding) => finding.message));
    const blockingIssues = [...missingEvidence, ...dependencyBlockers, ...sequencingIssues];
    const warnings = [...handoffBlockers, ...reviewBoundaryWarnings];
    const recoveryGuidance = buildTaskReadinessRecoveryGuidance({
        taskDefinitionPath: taskDefinitionPath.relative,
        missingEvidence,
        dependencyBlockers,
        sequencingIssues,
        handoffBlockers,
        reviewBoundaryWarnings,
    });
    const findings = [
        ...buildReviewFindings('TASK_READINESS_MISSING_EVIDENCE', 'error', missingEvidence.filter((message) => !materializationBlockers.includes(message) &&
            !runtimeBaselinePreconditionMessages.includes(message) &&
            !validationCoverageBlockingMessages.includes(message) &&
            !validationInputBlockingMessages.includes(message) &&
            !contractImpact.blockingIssues.includes(message) &&
            !canonicalLifecycleTargetMessages.includes(message)), taskDefinitionPath.relative),
        ...(canonicalLifecycleTargetPaths.length === 0
            ? []
            : [
                {
                    code: 'TASK_READINESS_LIFECYCLE_ARTIFACT_TARGET_INVALID',
                    message: canonicalLifecycleTargetMessages[0],
                    severity: 'error',
                    path: taskDefinitionPath.relative,
                    affectedPaths: canonicalLifecycleTargetPaths.map((targetPath) => ({
                        role: 'declared-target',
                        path: targetPath,
                        description: 'Canonical task lifecycle artifact is command-owned, not implementation scope.',
                    })),
                    recovery: 'Remove the canonical task-definition and implementation-summary paths from Implementation Target Paths, then rerun task readiness-review. The review performs no repair writes.',
                },
            ]),
        ...runtimeBaselinePreconditions.findings,
        ...materializationBlockers.map((message) => ({
            code: 'TASK_READINESS_LINK_MATERIALIZATION_REQUIRED',
            message,
            severity: 'error',
            path: taskDefinitionPath.relative,
            recovery: `Preview and apply safe link materialization before creating a fresh readiness review: node dist/cli/index.js link materialize --dry-run --artifact ${taskDefinitionPath.relative} --format json`,
            recommendedCommand: `node dist/cli/index.js link materialize --dry-run --artifact ${taskDefinitionPath.relative} --format json`,
            noWriteBoundary: 'Task readiness review is read-only and never materializes Markdown links.',
        })),
        ...buildReviewFindings('TASK_READINESS_DEPENDENCY_BLOCKER', 'error', dependencyBlockers, taskDefinitionPath.relative),
        ...buildReviewFindings('TASK_READINESS_SEQUENCING_BLOCKER', 'error', sequencingIssues, taskDefinitionPath.relative),
        ...buildReviewFindings('TASK_READINESS_HANDOFF_BLOCKER', 'warning', handoffBlockers, pairedImplementationSummaryPath),
        ...buildReviewFindings('TASK_READINESS_REVIEW_BOUNDARY_WARNING', 'warning', reviewBoundaryWarnings.filter((message) => !validationCoverageWarningMessages.includes(message) && !contractImpactWarningMessages.includes(message)), milestoneReconciliationPath ?? pairedImplementationSummaryPath),
        ...validationCoverage.findings,
        ...validationInputCoverage.issues.map((issue) => (0, validation_input_coverage_1.createValidationInputCoverageFinding)({
            issue,
            codePrefix: 'TASK',
            artifactPath: taskDefinitionPath.relative,
            reviewBoundary: 'task-readiness-review',
        })),
        ...contractImpact.findings,
        ...heuristicFindings,
    ];
    return {
        taskRevision,
        repositoryRoot,
        taskDefinitionPath: taskDefinitionPath.relative,
        authoredReadiness: readiness?.trim() || null,
        authorizationRevision,
        authorizationState,
        currentAttemptState,
        reviewedReadiness: readiness?.trim() || null,
        readinessStatus,
        handoffStatus,
        pairedImplementationSummaryPath,
        milestoneReconciliationPath,
        workflowTopology,
        reviewBoundaryKind: workflowTopology?.taskSummaryReviewBoundary ?? null,
        reconciliationArtifactKind: workflowTopology?.reconciliationArtifactKind ?? null,
        reconciliationRequired: workflowTopology?.reconciliationRequired ?? null,
        missingEvidence,
        dependencyBlockers,
        sequencingIssues,
        handoffBlockers,
        reviewBoundaryWarnings,
        blockingIssues,
        warnings,
        recoveryGuidance,
        findings,
        executionProfileReadiness,
        declaredAgentMode: policyProjection.declaredAgentMode,
        effectiveAgentMode: policyProjection.effectiveAgentMode,
        agentModeSource: policyProjection.agentModeSource,
        evidenceProfile: policyProjection.evidenceProfile,
        evidenceProfileSource: policyProjection.evidenceProfileSource,
        compatibilityEvidence: policyProjection.compatibilityEvidence,
        runtimeCriterionOwnership,
        validationCoverage,
        validationInputCoverage,
        contractImpact,
    };
}
function projectReadinessAuthorizationState(projection) {
    const authorization = projection.task.readinessAuthorization;
    const anyAuthorization = authorization.id !== null ||
        authorization.waiverId !== null ||
        authorization.taskRevision !== null ||
        authorization.protocolVersion !== null ||
        authorization.reviewer !== null ||
        authorization.reviewedAt !== null;
    if (!anyAuthorization)
        return 'absent';
    if (!authorization.complete || !authorization.valid)
        return 'invalid';
    if (!authorization.applicable)
        return 'stale';
    return authorization.kind === 'waiver' ? 'waived-current' : 'current';
}
function projectReadinessAttemptState(repositoryRoot, taskDefinitionPath, taskText, summaryPath, summaryText, projection) {
    const current = projection.summary?.currentAttempt ?? null;
    if (current === null) {
        return {
            state: (projection.summary?.attempts.length ?? 0) > 0 ? 'closed' : 'absent',
            attemptId: null,
            baselineId: null,
        };
    }
    if (current.closedAt !== null) {
        return { state: 'closed', attemptId: current.attemptId, baselineId: null };
    }
    if (summaryText === null || current.attemptId === null) {
        return { state: 'open-evidence-bearing', attemptId: current.attemptId, baselineId: null };
    }
    let baseline = null;
    try {
        baseline = (0, task_cycle_runtime_attribution_1.readAttemptRuntimeBaseline)(summaryPath, summaryText, current.attemptId);
    }
    catch {
        return { state: 'open-evidence-bearing', attemptId: current.attemptId, baselineId: null };
    }
    const baselineId = baseline?.baselineId ?? null;
    if ((0, task_attempts_1.inspectTaskAttemptSupersessionEvidence)(summaryText, current.attemptId).length > 0) {
        return { state: 'open-evidence-bearing', attemptId: current.attemptId, baselineId };
    }
    if (baseline === null) {
        return { state: 'open-no-evidence', attemptId: current.attemptId, baselineId: null };
    }
    try {
        if ((0, task_attempts_1.inspectSupersessionTargetDelta)(repositoryRoot, taskDefinitionPath, taskText, baseline).length > 0) {
            return { state: 'open-evidence-bearing', attemptId: current.attemptId, baselineId };
        }
    }
    catch (error) {
        if (error instanceof task_attempts_1.TaskAttemptSupersedeError && error.code === 'git-inspection-unavailable') {
            throw (0, errors_1.createUsageError)(error.message, [
                'Restore Git inspection before relying on readiness navigation; no implementation delta was inferred.',
            ]);
        }
        throw error;
    }
    return {
        state: 'open-baseline-only',
        attemptId: current.attemptId,
        baselineId,
    };
}
function buildReadinessNextAction(inspection, reviewedBy, reviewedAt) {
    if (inspection.authorizationState === 'stale' &&
        inspection.currentAttemptState.state === 'open-evidence-bearing' &&
        inspection.currentAttemptState.attemptId !== null) {
        const candidates = (0, task_contract_revision_recovery_1.discoverTaskContractRevisionRecoverySync)(inspection.repositoryRoot, inspection.taskDefinitionPath);
        const candidate = candidates.length === 1 ? candidates[0] : null;
        if (candidate !== null) {
            return {
                reasonCode: 'contract_revision_requires_evidence_recovery',
                command: 'task attempt-contract-revise',
                argv: [
                    'day-shift',
                    'task',
                    'attempt-contract-revise',
                    '--revision-run-directory',
                    candidate.runDirectory,
                    '--task-definition',
                    inspection.taskDefinitionPath,
                    '--attempt-id',
                    inspection.currentAttemptState.attemptId,
                    '--task-revision',
                    inspection.taskRevision,
                    '--checkpoint-id',
                    candidate.checkpointId,
                    '--recorded-by',
                    reviewedBy,
                    '--recorded-at',
                    reviewedAt,
                    '--reason',
                    'Preserve evidence after the accepted task contract revision.',
                    '--dry-run',
                ],
                callable: true,
                writeCapable: true,
            };
        }
        const adoptionCandidates = (0, task_contract_revision_adoption_1.discoverTaskContractRevisionAdoptionSync)(inspection.repositoryRoot, inspection.taskDefinitionPath);
        const adoption = adoptionCandidates.length === 1 ? adoptionCandidates[0] : null;
        if (adoption !== null) {
            return {
                reasonCode: 'contract_revision_requires_checkpoint_adoption',
                command: 'resume run revise-contract',
                argv: [
                    'day-shift',
                    'resume',
                    'run',
                    'revise-contract',
                    '--run-directory',
                    adoption.runDirectory,
                    '--review-result',
                    adoption.sourceEvidencePath,
                    '--active-artifact',
                    inspection.taskDefinitionPath,
                    '--recorded-by',
                    reviewedBy,
                    '--recorded-at',
                    reviewedAt,
                    '--reason',
                    'Adopt verified predecessor readiness evidence into the replacement strict run.',
                    '--rollback-gate',
                    'task-readiness',
                    '--dry-run',
                ],
                callable: true,
                writeCapable: true,
            };
        }
    }
    if (inspection.authorizationState === 'stale' &&
        inspection.currentAttemptState.state === 'open-baseline-only' &&
        inspection.currentAttemptState.attemptId !== null) {
        const argv = [
            'day-shift',
            'task',
            'attempt-supersede',
            '--task-definition',
            inspection.taskDefinitionPath,
            '--attempt-id',
            inspection.currentAttemptState.attemptId,
            '--task-revision',
            inspection.taskRevision,
            '--recorded-by',
            reviewedBy,
            '--recorded-at',
            reviewedAt,
            '--reason',
            'Authorized planning-contract revision after a pre-write runtime baseline.',
            '--dry-run',
        ];
        return {
            reasonCode: 'contract_revision_requires_attempt_supersession',
            command: 'task attempt-supersede',
            argv,
            callable: true,
            writeCapable: true,
        };
    }
    if (inspection.authorizationState === 'stale') {
        return {
            reasonCode: 'stale_readiness_authorization',
            command: inspection.currentAttemptState.state === 'absent' ? 'task readiness-authorize' : null,
            argv: null,
            callable: false,
            writeCapable: inspection.currentAttemptState.state === 'absent' ? true : null,
        };
    }
    if (inspection.readinessStatus === 'ready to implement') {
        return {
            reasonCode: 'readiness_review_complete',
            command: 'task readiness-authorize',
            argv: null,
            callable: false,
            writeCapable: true,
        };
    }
    return {
        reasonCode: 'readiness_blocked',
        command: null,
        argv: null,
        callable: false,
        writeCapable: null,
    };
}
function readDeclaredTaskSlugs(markdownText) {
    const lines = markdownText.split(/\r?\n/);
    const sectionStart = lines.findIndex((line) => line.trim() === '## Tasks');
    if (sectionStart === -1)
        return [];
    const slugs = [];
    for (let index = sectionStart + 1; index < lines.length; index += 1) {
        if (/^##\s+/u.test(lines[index]))
            break;
        const declaration = (0, planning_document_utils_1.parseDeclaredChildSlugBullet)(lines[index].trim());
        if (declaration !== null)
            slugs.push(declaration.slug);
    }
    return slugs;
}
function resolveDurablyMappedDependencyPath(repositoryRoot, sourcePath) {
    const migrationDirectory = node_path_1.default.join(repositoryRoot, '.day-shift', 'state', 'migrations');
    let recordNames;
    try {
        recordNames = node_fs_1.default
            .readdirSync(migrationDirectory)
            .filter((name) => /^workspace-structure-[a-f0-9]{16}\.json$/u.test(name))
            .sort();
    }
    catch {
        return null;
    }
    const destinations = new Set();
    for (const recordName of recordNames) {
        let record;
        try {
            record = JSON.parse(node_fs_1.default.readFileSync(node_path_1.default.join(migrationDirectory, recordName), 'utf8'));
        }
        catch {
            continue;
        }
        if (typeof record !== 'object' ||
            record === null ||
            !('schemaVersion' in record) ||
            record.schemaVersion !== 1 ||
            !('migrationKind' in record) ||
            record.migrationKind !== 'workspace-structure' ||
            !('transactionState' in record) ||
            record.transactionState !== 'authorized' ||
            !('pathMappings' in record) ||
            !Array.isArray(record.pathMappings)) {
            continue;
        }
        for (const mapping of record.pathMappings) {
            if (typeof mapping !== 'object' ||
                mapping === null ||
                !('sourcePath' in mapping) ||
                mapping.sourcePath !== sourcePath ||
                !('destinationPath' in mapping) ||
                typeof mapping.destinationPath !== 'string') {
                continue;
            }
            try {
                const parsedDestination = (0, paths_1.parseRepositoryRelativePath)(mapping.destinationPath);
                const destinationAbsolutePath = node_path_1.default.join(repositoryRoot, parsedDestination.normalizedPath);
                if (node_fs_1.default.existsSync(destinationAbsolutePath)) {
                    destinations.add(parsedDestination.normalizedPath);
                }
            }
            catch {
                continue;
            }
        }
    }
    return destinations.size === 1 ? [...destinations][0] : null;
}
/** Computes the stable protocol-v1 identity for complete revision-bound review evidence. */
function computeTaskReadinessReviewId(review) {
    const boundEvidence = { ...review, repositoryRoot: undefined };
    return `task-readiness-review-${(0, node_crypto_1.createHash)('sha256')
        .update(canonicalJson(boundEvidence))
        .digest('hex')
        .slice(0, 24)}`;
}
function canonicalJson(value) {
    if (Array.isArray(value))
        return `[${value.map((item) => (item === undefined ? 'null' : canonicalJson(item))).join(',')}]`;
    if (value !== null && typeof value === 'object') {
        const record = value;
        return `{${Object.keys(record)
            .filter((key) => record[key] !== undefined)
            .sort()
            .map((key) => `${JSON.stringify(key)}:${canonicalJson(record[key])}`)
            .join(',')}}`;
    }
    return value === undefined ? 'null' : JSON.stringify(value);
}
function requireReviewActor(value) {
    if (typeof value !== 'string' || value.trim() === '') {
        throw (0, errors_1.createUsageError)('Task readiness review requires an explicit non-empty reviewer.');
    }
    return value.trim();
}
function requireReviewTime(value) {
    if (typeof value !== 'string' || value.trim() === '' || !(0, task_lifecycle_1.isTaskLifecycleTimestamp)(value.trim())) {
        throw (0, errors_1.createUsageError)('Task readiness review requires an explicit ISO-8601 review time.');
    }
    return (0, task_lifecycle_timestamps_1.requireObservedLifecycleTimestamp)({
        value: value.trim(),
        field: 'readiness_reviewed_at',
        label: 'Task readiness review time',
    });
}
function buildTaskReadinessRecoveryGuidance(options) {
    const guidance = [];
    if (options.missingEvidence.length > 0) {
        if (options.missingEvidence.some((message) => message.includes('safely materializable planning link'))) {
            guidance.push(`Run 'node dist/cli/index.js link materialize --dry-run --artifact ${options.taskDefinitionPath} --format json', review the candidates, apply with --write, then create a fresh readiness review with explicit --reviewed-by and --reviewed-at values.`);
        }
        guidance.push(`Update '${options.taskDefinitionPath}' to supply the missing readiness evidence before implementation starts.`);
    }
    if (options.dependencyBlockers.length > 0) {
        if (options.dependencyBlockers.some((message) => message.includes('is prose, not a repository-relative artifact path'))) {
            guidance.push("Move prose dependency bullets out of '## Dependencies' into Upstream Context, Current Behavior, or Assumptions, or replace them with concrete repository-relative artifact paths.");
        }
        guidance.push('Create, restore, or relink the cited dependency artifacts before implementation.');
    }
    if (options.sequencingIssues.length > 0) {
        guidance.push('Correct later-sibling dependencies or reorder the task sequence before implementation.');
    }
    if (options.handoffBlockers.length > 0) {
        guidance.push(`Restore the paired implementation-summary surface before handoff, for example with 'node dist/cli/index.js implementation-summary build --task-definition ${options.taskDefinitionPath}'.`);
    }
    if (options.reviewBoundaryWarnings.length > 0) {
        guidance.push('Carry review-boundary warnings forward as milestone-handoff evidence only; do not treat them as permission to write during readiness review.');
    }
    return guidance;
}
function buildReviewFindings(code, severity, messages, artifactPath) {
    return messages.map((message) => ({
        code,
        message,
        severity,
        path: artifactPath,
    }));
}
function resolveTaskDefinitionPath(repositoryRoot, inputPath) {
    try {
        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 {
            relative: parsed.normalizedPath,
            absolute: node_path_1.default.join(repositoryRoot, parsed.normalizedPath),
        };
    }
    catch (error) {
        if (error instanceof Error && error.name === 'RuntimeError') {
            throw error;
        }
        throw (0, errors_1.createUsageError)(`Invalid --task-definition path '${inputPath}'.`, [
            error instanceof Error ? error.message : String(error),
        ]);
    }
}
function parseTaskDocument(filePath, fileText) {
    const parsed = (0, planning_artifact_document_1.parsePlanningArtifactDocument)(fileText);
    if (!parsed.hasFrontMatter) {
        if (parsed.diagnostics.some((diagnostic) => diagnostic.code === 'unterminated-front-matter')) {
            throw (0, errors_1.createUsageError)(`Artifact '${(0, front_matter_utils_1.toRepositoryLikePath)(filePath)}' has malformed YAML front matter.`);
        }
        throw (0, errors_1.createUsageError)(`Artifact '${(0, front_matter_utils_1.toRepositoryLikePath)(filePath)}' is missing YAML front matter.`);
    }
    const sections = new Map();
    for (const section of parsed.sections)
        sections.set(section.heading, section.contentText.trim());
    return {
        frontMatter: {
            lines: parsed.frontMatterLines,
            contentLines: parsed.bodyText.split(/\r?\n/),
        },
        sections,
    };
}
function parseFrontMatter(filePath, fileText) {
    const parsed = (0, planning_artifact_document_1.parsePlanningArtifactDocument)(fileText);
    if (!parsed.hasFrontMatter) {
        if (parsed.diagnostics.some((diagnostic) => diagnostic.code === 'unterminated-front-matter')) {
            throw (0, errors_1.createUsageError)(`Artifact '${(0, front_matter_utils_1.toRepositoryLikePath)(filePath)}' has malformed YAML front matter.`);
        }
        throw (0, errors_1.createUsageError)(`Artifact '${(0, front_matter_utils_1.toRepositoryLikePath)(filePath)}' is missing YAML front matter.`);
    }
    return { lines: parsed.frontMatterLines, contentLines: parsed.bodyText.split(/\r?\n/) };
}
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 isAllowedReadiness(value) {
    return (value === 'needs_more_evidence' ||
        value === 'ready_to_implement' ||
        value === 'needs more evidence' ||
        value === 'ready' ||
        value === 'ready to implement' ||
        value === 'blocked' ||
        value === 'completed');
}
function isIncompleteSection(value) {
    const trimmed = value.trim();
    if (trimmed.length === 0) {
        return true;
    }
    return PLACEHOLDER_PATTERN.test(stripMarkdownCode(trimmed));
}
function isOpenQuestionsResolved(sectionText) {
    const normalized = sectionText
        .split(/\r?\n/)
        .map((line) => line.trim())
        .filter((line) => line.length > 0);
    return normalized.length === 1 && normalized[0] === '- None currently.';
}
function detectLeakedTemplatePhrases(fileText) {
    const matches = new Set();
    for (const phrase of LEAKED_TEMPLATE_PHRASES) {
        const expression = new RegExp(escapeRegExp(phrase), 'i');
        if (expression.test(fileText)) {
            matches.add(phrase);
        }
    }
    return [...matches];
}
function detectUnresolvedPlaceholders(fileText) {
    const matches = stripMarkdownCode(fileText).match(UNRESOLVED_PLACEHOLDER_PATTERN) ?? [];
    const unique = new Set(matches.map((match) => match.replace(/\s+/g, '')));
    return [...unique].sort();
}
function stripMarkdownCode(value) {
    return value.replace(FENCED_CODE_BLOCK_PATTERN, '\n').replace(INLINE_CODE_SPAN_PATTERN, '');
}
function escapeRegExp(value) {
    return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
function extractDependencyPaths(sectionText) {
    return extractBulletedPaths(sectionText);
}
function isArtifactPathLike(dependencyPath) {
    if (/[,\s;]/.test(dependencyPath)) {
        return false;
    }
    return (dependencyPath.startsWith('.') ||
        dependencyPath.includes('/') ||
        /^[A-Za-z0-9_.-]+\.[A-Za-z0-9]+$/.test(dependencyPath));
}
function inspectTaskDependencyLifecycle(repositoryRoot, dependencyPath) {
    const pairPaths = resolveTaskDependencyPairPaths(dependencyPath);
    if (pairPaths === null) {
        return null;
    }
    const taskDefinitionAbsolutePath = node_path_1.default.join(repositoryRoot, pairPaths.taskDefinitionPath);
    const implementationSummaryAbsolutePath = node_path_1.default.join(repositoryRoot, pairPaths.implementationSummaryPath);
    const missingPairPaths = [
        node_fs_1.default.existsSync(taskDefinitionAbsolutePath) ? null : pairPaths.taskDefinitionPath,
        node_fs_1.default.existsSync(implementationSummaryAbsolutePath) ? null : pairPaths.implementationSummaryPath,
    ].filter((candidate) => candidate !== null);
    if (missingPairPaths.length > 0) {
        return `Predecessor task dependency '${dependencyPath}' is missing canonical pair artifact${missingPairPaths.length === 1 ? '' : 's'}: ${missingPairPaths.join(', ')}.`;
    }
    const projection = (0, task_lifecycle_1.projectTaskLifecyclePair)({
        taskDefinition: node_fs_1.default.readFileSync(taskDefinitionAbsolutePath, 'utf8'),
        implementationSummary: node_fs_1.default.readFileSync(implementationSummaryAbsolutePath, 'utf8'),
    });
    if (projection.acceptedCompleted) {
        return null;
    }
    if (projection.task.status === 'cancelled') {
        return `Predecessor task dependency '${dependencyPath}' is cancelled, not completed and accepted.`;
    }
    if (projection.reviewDisposition === 'changes_requested') {
        return `Predecessor task dependency '${dependencyPath}' has changes_requested disposition, not accepted completion.`;
    }
    if (projection.implementationStatus === 'blocked' || projection.reviewDisposition === 'blocked') {
        return `Predecessor task dependency '${dependencyPath}' is blocked, not completed and accepted.`;
    }
    if (projection.task.status === 'completed' &&
        projection.reviewDisposition !== 'accepted' &&
        projection.reviewDisposition !== 'accepted_with_follow_up') {
        return `Predecessor task dependency '${dependencyPath}' is completed without accepted or accepted_with_follow_up disposition.`;
    }
    if (projection.blockingFindings.length > 0) {
        const findingCodes = [...new Set(projection.blockingFindings.map((finding) => finding.code))].sort();
        return `Predecessor task dependency '${dependencyPath}' has invalid lifecycle evidence (${findingCodes.join(', ')}).`;
    }
    return `Predecessor task dependency '${dependencyPath}' is nonterminal; completion with accepted or accepted_with_follow_up disposition is required.`;
}
function resolveTaskDependencyPairPaths(dependencyPath) {
    const normalizedPath = (0, front_matter_utils_1.toRepositoryLikePath)(dependencyPath);
    const fileName = node_path_1.default.posix.basename(normalizedPath);
    if (fileName !== 'task-definition.md' && fileName !== 'implementation-summary.md') {
        return null;
    }
    const taskDirectory = node_path_1.default.posix.dirname(normalizedPath);
    return {
        taskDefinitionPath: node_path_1.default.posix.join(taskDirectory, 'task-definition.md'),
        implementationSummaryPath: node_path_1.default.posix.join(taskDirectory, 'implementation-summary.md'),
    };
}
function extractBulletedPaths(sectionText) {
    const dependencies = [];
    for (const line of sectionText.split(/\r?\n/)) {
        const trimmed = line.trim();
        if (!trimmed.startsWith('- ')) {
            continue;
        }
        const item = trimmed.slice(2).trim();
        if (/^none(?: currently)?\.?$/i.test(item) || /^pending\b/i.test(item)) {
            continue;
        }
        const backtickMatch = item.match(/^`([^`]+)`$/);
        dependencies.push(backtickMatch === null ? item : backtickMatch[1]);
    }
    return dependencies;
}
function forbidsSharedImplementationOverlap(sectionText) {
    return (/not [^.]*shared runtime implementation/i.test(sectionText) ||
        /keep executable [^.]* out of this task/i.test(sectionText) ||
        /later helper, CLI, and shared coverage work belongs to/i.test(sectionText));
}
function detectLaterImplementationTargetOverlap(repositoryRoot, taskDefinitionPath, implementationTargetPathsText) {
    const currentContext = resolveSequencingContext(taskDefinitionPath, taskDefinitionPath.match(/\/tasks\/([^/]+)\/task-definition\.md$/)?.[1]);
    if (currentContext.taskSlug === null || currentContext.milestoneTasksPrefix === null) {
        return [];
    }
    const currentTargetEvidence = (0, validation_1.readTaskDeclaredTargetPathEvidence)(taskDefinitionPath, `## Implementation Target Paths\n\n${implementationTargetPathsText}`);
    const currentTargets = new Set(currentTargetEvidence.explicitTargetPaths);
    if (currentTargets.size === 0) {
        return [];
    }
    const tasksDirectoryPath = node_path_1.default.join(repositoryRoot, `${currentContext.milestoneTasksPrefix}`);
    if (!node_fs_1.default.existsSync(tasksDirectoryPath)) {
        return [];
    }
    const overlappingPaths = new Set();
    for (const entry of node_fs_1.default.readdirSync(tasksDirectoryPath, { withFileTypes: true })) {
        if (!entry.isDirectory()) {
            continue;
        }
        const siblingSlug = entry.name;
        if (siblingSlug === currentContext.taskSlug) {
            continue;
        }
        const siblingOrder = parseOrderedPrefix(siblingSlug);
        const currentOrder = parseOrderedPrefix(currentContext.taskSlug);
        if (siblingOrder === null || currentOrder === null || siblingOrder <= currentOrder) {
            continue;
        }
        if (!/-implement-/i.test(siblingSlug)) {
            continue;
        }
        const siblingTaskDefinitionPath = node_path_1.default.join(tasksDirectoryPath, siblingSlug, 'task-definition.md');
        if (!node_fs_1.default.existsSync(siblingTaskDefinitionPath)) {
            continue;
        }
        const siblingDocument = parseTaskDocument((0, front_matter_utils_1.toRepositoryLikePath)(node_path_1.default.relative(repositoryRoot, siblingTaskDefinitionPath)), node_fs_1.default.readFileSync(siblingTaskDefinitionPath, 'utf8'));
        const siblingTargetsText = siblingDocument.sections.get('Implementation Target Paths');
        if (siblingTargetsText === undefined) {
            continue;
        }
        const siblingTargetEvidence = (0, validation_1.readTaskDeclaredTargetPathEvidence)((0, front_matter_utils_1.toRepositoryLikePath)(node_path_1.default.relative(repositoryRoot, siblingTaskDefinitionPath)), `## Implementation Target Paths\n\n${siblingTargetsText}`);
        for (const siblingTarget of siblingTargetEvidence.explicitTargetPaths) {
            if (currentTargets.has(siblingTarget)) {
                overlappingPaths.add(siblingTarget);
            }
        }
    }
    return [...overlappingPaths].sort();
}
function resolveSequencingContext(taskDefinitionPath, taskSlugRaw) {
    const observedMatch = taskDefinitionPath.match(/\/tasks\/([^/]+)\/task-definition\.md$/);
    const taskSlug = observedMatch?.[1]?.trim() || taskSlugRaw?.trim() || null;
    if (taskSlug === null || !(0, paths_1.isCanonicalSlug)(taskSlug)) {
        return {
            taskSlug: null,
            milestoneTasksPrefix: null,
        };
    }
    const token = `/tasks/${taskSlug}/task-definition.md`;
    const tokenIndex = taskDefinitionPath.lastIndexOf(token);
    if (tokenIndex === -1) {
        return {
            taskSlug,
            milestoneTasksPrefix: null,
        };
    }
    return {
        taskSlug,
        milestoneTasksPrefix: taskDefinitionPath.slice(0, tokenIndex + 7),
    };
}
function detectLaterSiblingDependency(context, dependencyPath) {
    if (context.taskSlug === null || context.milestoneTasksPrefix === null) {
        return null;
    }
    if (!dependencyPath.startsWith(context.milestoneTasksPrefix)) {
        return null;
    }
    const dependencyMatch = dependencyPath.match(/\/tasks\/([^/]+)\/task-definition\.md$/);
    if (dependencyMatch === null) {
        return null;
    }
    const currentOrder = parseOrderedPrefix(context.taskSlug);
    const dependencyOrder = parseOrderedPrefix(dependencyMatch[1]);
    if (currentOrder === null || dependencyOrder === null) {
        return null;
    }
    if (dependencyOrder > currentOrder) {
        return `Dependency '${dependencyPath}' references later-numbered sibling task '${dependencyMatch[1]}'.`;
    }
    return null;
}
function parseOrderedPrefix(slug) {
    const match = slug.match(/^(\d+)-/);
    if (match === null) {
        return null;
    }
    return Number.parseInt(match[1], 10);
}
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 resolveMilestoneOverviewPath(taskDefinitionPath, repositoryRoot) {
    const normalizedPath = (0, front_matter_utils_1.toRepositoryLikePath)(taskDefinitionPath);
    const marker = '/tasks/';
    const markerIndex = normalizedPath.lastIndexOf(marker);
    if (markerIndex === -1) {
        return null;
    }
    const milestoneDirectory = normalizedPath.slice(0, markerIndex);
    for (const fileName of ['milestone-overview.md', 'overview.md']) {
        const relative = `${milestoneDirectory}/${fileName}`;
        const absolute = node_path_1.default.join(repositoryRoot, relative);
        if (node_fs_1.default.existsSync(absolute)) {
            return { relative, absolute };
        }
    }
    return null;
}
