"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.WORKFLOW_EXPLAIN_TRUST_LANES = void 0;
exports.inventoryPlanning = inventoryPlanning;
exports.discoverPlanningWorkCandidates = discoverPlanningWorkCandidates;
exports.gapReportPlanning = gapReportPlanning;
exports.explainWorkflowForArtifact = explainWorkflowForArtifact;
exports.suggestPlanningNextAction = suggestPlanningNextAction;
exports.renderPlanningInventoryResult = renderPlanningInventoryResult;
exports.renderPlanningWorkCandidatesResult = renderPlanningWorkCandidatesResult;
exports.renderPlanningGapReportResult = renderPlanningGapReportResult;
exports.renderWorkflowExplainResult = renderWorkflowExplainResult;
exports.renderPlanningNextActionResult = renderPlanningNextActionResult;
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const config_contract_1 = require("../config/config-contract");
const config_layer_resolution_1 = require("../config/config-layer-resolution");
const errors_1 = require("../errors");
const output_1 = require("../output");
const paths_1 = require("../paths");
const planning_document_utils_1 = require("./planning-document-utils");
const planning_artifact_document_1 = require("./planning-artifact-document");
const workspace_discovery_1 = require("../workspace-discovery");
const artifact_lifecycle_1 = require("./artifact-lifecycle");
exports.WORKFLOW_EXPLAIN_TRUST_LANES = Object.freeze({
    selectedArtifact: "selected-artifact",
    workflowPolicy: "product-policy",
    promptPolicy: "product-policy",
    generatedGuidance: "generated-evidence",
    recommendedCommand: "command-metadata"
});
const PLACEHOLDER_PATTERN = /(\bTBD\b|\bTODO\b|^PLACEHOLDER$|^pending\b|{{\s*[A-Za-z0-9_.-]+\s*}})/im;
const INCOMPLETE_SUMMARY_PHRASES = [
    "Pending. This implementation summary is initialized",
    "None yet. Populate this section when implementation begins.",
    "Pending review after implementation.",
    "Residual risk remains until executable behavior and validation evidence are recorded."
];
const INCOMPLETE_RECONCILIATION_PHRASES = [
    "Pending. This reconciliation artifact is initialized",
    "- Pending. Add completed task implementation summaries as milestone execution work finishes.",
    "Pending. Add concrete next tasks here only if reconciliation identifies remaining work after review.",
    "Pending milestone review.",
    "Pending milestone review. No completed task implementation summaries are available yet.",
    "Pending milestone review. Evidence has been refreshed, but milestone acceptance still requires explicit human review."
];
function inventoryPlanning(options) {
    const scope = resolveScope(options.repositoryRoot, options.rootPath ?? ".day-shift/planning", true);
    const discovery = (0, workspace_discovery_1.discoverWorkspacePaths)({
        workspaceRoot: options.repositoryRoot,
        budgets: { files: 25_000, directories: 10_000, evidenceEntries: 50_000 },
        include: (entry) => entry.kind === "file" && isRecognizedArtifactFilename(entry.path) && (scope.kind !== "planning-root" || entry.path === scope.path || entry.path.startsWith(`${scope.path}/`))
    });
    const artifacts = scope.kind === "planning-root"
        ? [...discovery.paths].sort((left, right) => left.localeCompare(right)).map((artifactPath) => readArtifactRecord(options.repositoryRoot, artifactPath))
        : collectArtifactsForScope(options.repositoryRoot, scope);
    const findings = [];
    const grouped = groupArtifacts(artifacts);
    const taskByPath = new Map(grouped.taskDefinitionPaths.map((record) => [record.path, record]));
    for (const taskRecord of grouped.taskDefinitionPaths) {
        const expectedSummaryPath = pairedImplementationSummaryPath(taskRecord.path);
        const summaryRecord = grouped.implementationSummaryPaths.find((record) => record.path === expectedSummaryPath) ?? null;
        if (!isClosedTaskDefinition(taskRecord)) {
            continue;
        }
        if (summaryRecord === null) {
            findings.push(`Task definition '${taskRecord.path}' is missing paired implementation summary '${expectedSummaryPath}'.`);
            continue;
        }
        if (!isCompletedImplementationSummary(summaryRecord)) {
            findings.push(`Paired implementation summary '${summaryRecord.path}' is still incomplete for task '${taskRecord.path}'.`);
        }
        if (isCompletedImplementationSummary(summaryRecord)
            && (taskRecord.status !== "completed" || taskRecord.readiness !== "completed")) {
            findings.push(`Task definition '${taskRecord.path}' still carries stale lifecycle metadata after completed implementation evidence.`);
        }
    }
    for (const milestoneRecord of grouped.milestoneOverviewPaths) {
        const expectedReconciliationPath = pairedReconciliationPath(milestoneRecord.path);
        const reconciliationRecord = grouped.reconciliationPaths.find((record) => record.path === expectedReconciliationPath) ?? null;
        const allTaskSummariesComplete = areAllKnownTaskImplementationSummariesCompleteForMilestone(grouped.taskDefinitionPaths, grouped.implementationSummaryPaths, milestoneRecord.path);
        if (!allTaskSummariesComplete) {
            continue;
        }
        if (reconciliationRecord === null) {
            findings.push(`Milestone overview '${milestoneRecord.path}' is missing paired reconciliation '${expectedReconciliationPath}'.`);
            continue;
        }
        if (!isCompletedReconciliation(reconciliationRecord)) {
            findings.push(`Paired reconciliation '${reconciliationRecord.path}' is still incomplete for milestone '${milestoneRecord.path}'.`);
            continue;
        }
        if (milestoneRecord.status !== "completed") {
            findings.push(`Milestone overview '${milestoneRecord.path}' still carries stale status metadata after completed reconciliation evidence.`);
        }
    }
    for (const summaryRecord of grouped.implementationSummaryPaths) {
        if (summaryRecord.upstreamTaskDefinitionPath !== null
            && !taskByPath.has(summaryRecord.upstreamTaskDefinitionPath)) {
            findings.push(`Implementation summary '${summaryRecord.path}' points to missing task definition '${summaryRecord.upstreamTaskDefinitionPath}'.`);
        }
    }
    return {
        scopePath: scope.path,
        scopeKind: scope.kind,
        sliceOverviewPaths: grouped.sliceOverviewPaths.map((record) => record.path),
        phaseOverviewPaths: grouped.phaseOverviewPaths.map((record) => record.path),
        milestoneOverviewPaths: grouped.milestoneOverviewPaths.map((record) => record.path),
        taskDefinitionPaths: grouped.taskDefinitionPaths.map((record) => record.path),
        implementationSummaryPaths: grouped.implementationSummaryPaths.map((record) => record.path),
        reconciliationPaths: grouped.reconciliationPaths.map((record) => record.path),
        findings,
        discovery: discovery.evidence
    };
}
function discoverPlanningWorkCandidates(options) {
    const defaultLimit = 10;
    const requestedLimit = options.limit ?? defaultLimit;
    if (!Number.isInteger(requestedLimit) || requestedLimit <= 0) {
        throw (0, errors_1.createUsageError)("Planning work candidate limit must be a positive integer.", [
            `Received: ${String(requestedLimit)}`
        ]);
    }
    const scope = resolveScope(options.repositoryRoot, options.rootPath ?? ".day-shift/planning", true);
    const artifacts = collectArtifactsForScope(options.repositoryRoot, scope);
    const selectableRecords = artifacts.filter(isSelectablePlanningRecord);
    const incompleteRecords = selectableRecords.filter((record) => !isPlanningRecordCompleted(options.repositoryRoot, record));
    const frontierRecords = incompleteRecords.filter((record) => !incompleteRecords.some((candidate) => candidate.path !== record.path && isPlanningDescendant(candidate.path, record.path)));
    const candidates = frontierRecords.map((record) => buildPlanningWorkCandidate(options.repositoryRoot, record, selectableRecords));
    const returnedCandidates = candidates.slice(0, requestedLimit);
    return {
        scopePath: scope.path,
        scopeKind: scope.kind,
        defaultLimit,
        requestedLimit,
        totalCandidateCount: candidates.length,
        returnedCandidateCount: returnedCandidates.length,
        omittedCandidateCount: candidates.length - returnedCandidates.length,
        candidates: returnedCandidates,
        advisory: true,
        readOnly: true
    };
}
function gapReportPlanning(options) {
    const scope = resolveScope(options.repositoryRoot, options.scopePath ?? ".day-shift/planning", true);
    const gapMap = new Map();
    if (scope.kind === "planning-root") {
        const artifacts = collectArtifactsForScope(options.repositoryRoot, scope);
        const roots = pickGapAnalysisRoots(artifacts);
        for (const record of roots) {
            collectArtifactGaps(options.repositoryRoot, record, gapMap);
        }
    }
    else {
        collectArtifactGaps(options.repositoryRoot, readArtifactRecord(options.repositoryRoot, scope.path), gapMap);
    }
    return {
        scopePath: scope.path,
        scopeKind: scope.kind,
        gaps: [...gapMap.values()].sort((left, right) => left.path.localeCompare(right.path))
    };
}
function explainWorkflowForArtifact(options) {
    const scope = resolveScope(options.repositoryRoot, options.artifactPath, false);
    const record = readArtifactRecord(options.repositoryRoot, scope.path);
    const resolvedConfig = (0, config_contract_1.resolveDayShiftConfig)({
        repositoryContext: { root: options.repositoryRoot, detectionSource: "explicit", warnedAboutFallback: false }
    });
    switch (record.artifactType) {
        case "task_definition": {
            const summaryRecord = readArtifactIfExists(options.repositoryRoot, pairedImplementationSummaryPath(record.path));
            if (summaryRecord !== null && isCompletedImplementationSummary(summaryRecord)) {
                const promptResolution = resolveRequiredPromptReference(options.repositoryRoot, resolvedConfig.values, ".day-shift/prompts/user/implementation.next.md");
                return {
                    artifactPath: record.path,
                    artifactType: record.artifactType,
                    workflowPath: ".day-shift/workflows/04-summarize-and-reconcile.md",
                    promptPath: promptResolution.resolvedPromptPath,
                    promptResolution,
                    explanation: "Completed task execution evidence is already present, so the task now sits on the summarize-and-reconcile workflow boundary.",
                    recommendation: "Review task closeout evidence.",
                    recommendedCommand: `node dist/cli/index.js task review --task-definition ${record.path}`,
                    nextBoundary: "Review the paired implementation summary and then continue into milestone reconciliation without auto-closing metadata."
                };
            }
            const promptResolution = resolveRequiredPromptReference(options.repositoryRoot, resolvedConfig.values, ".day-shift/prompts/user/task.next.md");
            return {
                artifactPath: record.path,
                artifactType: record.artifactType,
                workflowPath: ".day-shift/workflows/03-implement-from-task.md",
                promptPath: promptResolution.resolvedPromptPath,
                promptResolution,
                explanation: (0, artifact_lifecycle_1.isTaskReadyToImplement)(record)
                    ? "This task definition is implementation-ready, so the task implementation workflow applies."
                    : "Task definitions route through the implement-from-task workflow, which begins with a readiness gate before code changes.",
                recommendation: (0, artifact_lifecycle_1.isTaskReadyToImplement)(record)
                    ? "Implement the task using the task handoff workflow."
                    : "Re-run the readiness gate before implementation.",
                recommendedCommand: (0, artifact_lifecycle_1.isTaskReadyToImplement)(record)
                    ? null
                    : `node dist/cli/index.js task readiness-review --task-definition ${record.path}`,
                nextBoundary: "Run the readiness check before code changes, then implement within scope and update the paired implementation summary plus task-definition closeout metadata."
            };
        }
        case "implementation_summary": {
            const promptResolution = resolveRequiredPromptReference(options.repositoryRoot, resolvedConfig.values, isCompletedImplementationSummary(record)
                ? ".day-shift/prompts/user/implementation.review.md"
                : ".day-shift/prompts/user/implementation.build.md");
            return {
                artifactPath: record.path,
                artifactType: record.artifactType,
                workflowPath: ".day-shift/workflows/04-summarize-and-reconcile.md",
                promptPath: promptResolution.resolvedPromptPath,
                promptResolution,
                explanation: "Implementation summaries belong to the summarize-and-reconcile workflow, which tracks task execution evidence and downstream review handoff.",
                recommendation: isCompletedImplementationSummary(record)
                    ? "Review implementation evidence before milestone rollup."
                    : "Complete the task execution summary.",
                recommendedCommand: record.upstreamTaskDefinitionPath === null
                    ? null
                    : `node dist/cli/index.js implementation-summary ${isCompletedImplementationSummary(record) ? "review" : "build"} --task-definition ${record.upstreamTaskDefinitionPath}`,
                nextBoundary: isCompletedImplementationSummary(record)
                    ? "Use implementation-summary review for read-only evaluation, then continue into milestone reconciliation when the milestone is ready."
                    : "Refresh the paired implementation summary evidence, then use implementation-summary review as the read-only validation boundary."
            };
        }
        case "milestone_overview": {
            const reconciliationRecord = readArtifactIfExists(options.repositoryRoot, pairedReconciliationPath(record.path));
            const allTaskSummariesComplete = areAllTaskImplementationSummariesComplete(options.repositoryRoot, record.path);
            if (allTaskSummariesComplete) {
                const promptResolution = resolveRequiredPromptReference(options.repositoryRoot, resolvedConfig.values, reconciliationRecord !== null && isCompletedReconciliation(reconciliationRecord)
                    ? ".day-shift/prompts/user/reconciliation.review.md"
                    : ".day-shift/prompts/user/reconciliation.build.md");
                return {
                    artifactPath: record.path,
                    artifactType: record.artifactType,
                    workflowPath: ".day-shift/workflows/04-summarize-and-reconcile.md",
                    promptPath: promptResolution.resolvedPromptPath,
                    promptResolution,
                    explanation: "All known task implementation summaries are complete, so milestone-level summarize-and-reconcile guidance applies.",
                    recommendation: reconciliationRecord !== null && isCompletedReconciliation(reconciliationRecord)
                        ? "Review milestone closure evidence."
                        : "Build or refresh the paired milestone reconciliation.",
                    recommendedCommand: `node dist/cli/index.js reconciliation ${reconciliationRecord !== null && isCompletedReconciliation(reconciliationRecord) ? "review" : "build"} --milestone-overview ${record.path}`,
                    nextBoundary: reconciliationRecord !== null && isCompletedReconciliation(reconciliationRecord)
                        ? "Use reconciliation review as read-only milestone closure evidence before any explicit metadata update."
                        : "Refresh or review the paired milestone reconciliation without treating that step as automatic closure authority."
                };
            }
            const promptResolution = resolveRequiredPromptReference(options.repositoryRoot, resolvedConfig.values, ".day-shift/prompts/user/task.next.md");
            return {
                artifactPath: record.path,
                artifactType: record.artifactType,
                workflowPath: ".day-shift/workflows/03-implement-from-task.md",
                promptPath: promptResolution.resolvedPromptPath,
                promptResolution,
                explanation: "Milestone reconciliation is premature until all task implementation summaries are complete.",
                recommendation: "Advance the next task beneath this milestone.",
                recommendedCommand: `node dist/cli/index.js planning gap-report --scope ${record.path}`,
                nextBoundary: "Select or create the next task beneath this milestone before moving into implementation or reconciliation."
            };
        }
        case "reconciliation": {
            const promptResolution = resolveRequiredPromptReference(options.repositoryRoot, resolvedConfig.values, isCompletedReconciliation(record)
                ? ".day-shift/prompts/user/reconciliation.review.md"
                : ".day-shift/prompts/user/reconciliation.build.md");
            return {
                artifactPath: record.path,
                artifactType: record.artifactType,
                workflowPath: ".day-shift/workflows/04-summarize-and-reconcile.md",
                promptPath: promptResolution.resolvedPromptPath,
                promptResolution,
                explanation: "Reconciliation artifacts are milestone review artifacts governed by the summarize-and-reconcile workflow.",
                recommendation: isCompletedReconciliation(record)
                    ? "Review reconciliation closure evidence."
                    : "Complete the milestone reconciliation.",
                recommendedCommand: record.upstreamMilestoneOverviewPath === null
                    ? null
                    : `node dist/cli/index.js reconciliation ${isCompletedReconciliation(record) ? "review" : "build"} --milestone-overview ${record.upstreamMilestoneOverviewPath}`,
                nextBoundary: isCompletedReconciliation(record)
                    ? "Keep further steps read-only unless a separate metadata update or follow-up task is explicitly chosen."
                    : "Complete or refresh the reconciliation contents, then use reconciliation review as the read-only closure check."
            };
        }
        case "phase_overview": {
            const phaseReadyForReview = areAllDeclaredMilestonesReconciled(options.repositoryRoot, record);
            const promptResolution = resolveRequiredPromptReference(options.repositoryRoot, resolvedConfig.values, phaseReadyForReview
                ? ".day-shift/prompts/user/phase.review.md"
                : ".day-shift/prompts/user/phase.next.md");
            return {
                artifactPath: record.path,
                artifactType: record.artifactType,
                workflowPath: phaseReadyForReview
                    ? ".day-shift/workflows/04-summarize-and-reconcile.md"
                    : ".day-shift/workflows/02-plan-from-spec.md",
                promptPath: promptResolution.resolvedPromptPath,
                promptResolution,
                explanation: phaseReadyForReview
                    ? "Every declared milestone has completed reconciliation evidence, so this phase is on the read-only phase review boundary even when overview status metadata is stale."
                    : "The phase still has declared milestone work without completed reconciliation evidence, so phase planning and milestone execution remain active.",
                recommendation: phaseReadyForReview
                    ? "Review phase closure evidence."
                    : "Inspect milestone coverage beneath this phase.",
                recommendedCommand: phaseReadyForReview
                    ? `node dist/cli/index.js phase review --phase-overview ${record.path}`
                    : `node dist/cli/index.js planning inventory --root ${node_path_1.default.posix.dirname(record.path)}`,
                nextBoundary: phaseReadyForReview
                    ? "Run read-only phase review before any separately authorized lifecycle metadata update."
                    : "Plan or inspect milestone structure here; downstream implementation happens only after a concrete task is selected."
            };
        }
        case "slice_overview": {
            const promptResolution = resolveRequiredPromptReference(options.repositoryRoot, resolvedConfig.values, ".day-shift/prompts/user/slice.next.md");
            return {
                artifactPath: record.path,
                artifactType: record.artifactType,
                workflowPath: ".day-shift/workflows/02-plan-from-spec.md",
                promptPath: promptResolution.resolvedPromptPath,
                promptResolution,
                explanation: "Slice overviews are planning-layer artifacts, so the planning workflow remains the relevant contract surface.",
                recommendation: "Inspect phase coverage beneath this slice.",
                recommendedCommand: `node dist/cli/index.js planning inventory --root ${node_path_1.default.posix.dirname(record.path)}`,
                nextBoundary: "Use this slice as planning context for phase selection, creation, or review rather than as an implementation handoff."
            };
        }
        default:
            return assertNever(record.artifactType);
    }
}
function suggestPlanningNextAction(options) {
    const scope = resolveScope(options.repositoryRoot, options.artifactPath, false);
    const record = readArtifactRecord(options.repositoryRoot, scope.path);
    const resolvedConfig = (0, config_contract_1.resolveDayShiftConfig)({
        repositoryContext: { root: options.repositoryRoot, detectionSource: "explicit", warnedAboutFallback: false }
    });
    switch (record.artifactType) {
        case "task_definition": {
            const summaryPath = pairedImplementationSummaryPath(record.path);
            const summaryRecord = readArtifactIfExists(options.repositoryRoot, summaryPath);
            if (summaryRecord !== null && isCompletedImplementationSummary(summaryRecord)) {
                const promptResolution = resolveRequiredPromptReference(options.repositoryRoot, resolvedConfig.values, ".day-shift/prompts/user/implementation.review.md");
                return {
                    artifactPath: record.path,
                    artifactType: record.artifactType,
                    recommendation: "Review task closeout evidence.",
                    reason: "Completed implementation evidence already exists, so the next safe step is a read-only review of closeout alignment before milestone rollup.",
                    command: `node dist/cli/index.js task review --task-definition ${record.path}`,
                    workflowPath: ".day-shift/workflows/04-summarize-and-reconcile.md",
                    promptPath: promptResolution.resolvedPromptPath,
                    promptResolution
                };
            }
            if (!(0, artifact_lifecycle_1.isTaskReadyToImplement)(record)) {
                const promptResolution = resolveRequiredPromptReference(options.repositoryRoot, resolvedConfig.values, ".day-shift/prompts/user/task.next.md");
                return {
                    artifactPath: record.path,
                    artifactType: record.artifactType,
                    recommendation: "Re-run the readiness gate before implementation.",
                    reason: "The task definition is not yet at the canonical implementation-handoff readiness token.",
                    command: `node dist/cli/index.js task readiness-review --task-definition ${record.path}`,
                    workflowPath: ".day-shift/workflows/03-implement-from-task.md",
                    promptPath: promptResolution.resolvedPromptPath,
                    promptResolution
                };
            }
            const promptResolution = resolveRequiredPromptReference(options.repositoryRoot, resolvedConfig.values, ".day-shift/prompts/user/task.next.md");
            return {
                artifactPath: record.path,
                artifactType: record.artifactType,
                recommendation: "Implement the task using the task handoff workflow.",
                reason: "The task is ready to implement and the paired implementation summary is not yet complete.",
                command: null,
                workflowPath: ".day-shift/workflows/03-implement-from-task.md",
                promptPath: promptResolution.resolvedPromptPath,
                promptResolution
            };
        }
        case "milestone_overview": {
            const reconciliationPath = pairedReconciliationPath(record.path);
            const reconciliationRecord = readArtifactIfExists(options.repositoryRoot, reconciliationPath);
            const allTaskSummariesComplete = areAllTaskImplementationSummariesComplete(options.repositoryRoot, record.path);
            if (!allTaskSummariesComplete) {
                const declaredTasks = readDeclaredChildSlugsFromDocument(record.document, "Tasks");
                const firstTaskSlug = declaredTasks[0] ?? null;
                const promptResolution = resolveRequiredPromptReference(options.repositoryRoot, resolvedConfig.values, ".day-shift/prompts/user/task.next.md");
                return {
                    artifactPath: record.path,
                    artifactType: record.artifactType,
                    recommendation: "Advance the next task beneath this milestone.",
                    reason: "Milestone reconciliation is premature until all task implementation summaries are complete.",
                    command: firstTaskSlug === null
                        ? null
                        : `node dist/cli/index.js planning gap-report --scope ${record.path}`,
                    workflowPath: ".day-shift/workflows/03-implement-from-task.md",
                    promptPath: promptResolution.resolvedPromptPath,
                    promptResolution
                };
            }
            if (reconciliationRecord === null) {
                const promptResolution = resolveRequiredPromptReference(options.repositoryRoot, resolvedConfig.values, ".day-shift/prompts/user/reconciliation.build.md");
                return {
                    artifactPath: record.path,
                    artifactType: record.artifactType,
                    recommendation: "Build the paired milestone reconciliation.",
                    reason: "All task execution summaries are complete, but the default milestone reconciliation artifact is still missing.",
                    command: `node dist/cli/index.js reconciliation build --milestone-overview ${record.path}`,
                    workflowPath: ".day-shift/workflows/04-summarize-and-reconcile.md",
                    promptPath: promptResolution.resolvedPromptPath,
                    promptResolution
                };
            }
            if (!isCompletedReconciliation(reconciliationRecord)) {
                const promptResolution = resolveRequiredPromptReference(options.repositoryRoot, resolvedConfig.values, ".day-shift/prompts/user/reconciliation.build.md");
                return {
                    artifactPath: record.path,
                    artifactType: record.artifactType,
                    recommendation: "Refresh and complete milestone reconciliation evidence.",
                    reason: "The paired milestone reconciliation exists but still carries placeholder or incomplete review state.",
                    command: `node dist/cli/index.js reconciliation build --milestone-overview ${record.path}`,
                    workflowPath: ".day-shift/workflows/04-summarize-and-reconcile.md",
                    promptPath: promptResolution.resolvedPromptPath,
                    promptResolution
                };
            }
            const promptResolution = resolveRequiredPromptReference(options.repositoryRoot, resolvedConfig.values, ".day-shift/prompts/user/milestone.review.md");
            return {
                artifactPath: record.path,
                artifactType: record.artifactType,
                recommendation: "Review milestone closure evidence.",
                reason: "The milestone already has reconciliation evidence, so the next safe step is a read-only milestone review.",
                command: `node dist/cli/index.js milestone review --milestone-overview ${record.path}`,
                workflowPath: ".day-shift/workflows/04-summarize-and-reconcile.md",
                promptPath: promptResolution.resolvedPromptPath,
                promptResolution
            };
        }
        case "implementation_summary": {
            const promptResolution = resolveRequiredPromptReference(options.repositoryRoot, resolvedConfig.values, isCompletedImplementationSummary(record)
                ? ".day-shift/prompts/user/implementation.review.md"
                : ".day-shift/prompts/user/implementation.build.md");
            return {
                artifactPath: record.path,
                artifactType: record.artifactType,
                recommendation: isCompletedImplementationSummary(record)
                    ? "Review implementation evidence before milestone rollup."
                    : "Complete the task execution summary.",
                reason: isCompletedImplementationSummary(record)
                    ? "The paired execution artifact is complete enough for read-only review and downstream reconciliation."
                    : "The summary still lacks completed execution evidence, so milestone-level review would be premature.",
                command: record.upstreamTaskDefinitionPath === null
                    ? null
                    : `node dist/cli/index.js implementation-summary review --task-definition ${record.upstreamTaskDefinitionPath}`,
                workflowPath: ".day-shift/workflows/04-summarize-and-reconcile.md",
                promptPath: promptResolution.resolvedPromptPath,
                promptResolution
            };
        }
        case "reconciliation": {
            const promptResolution = resolveRequiredPromptReference(options.repositoryRoot, resolvedConfig.values, isCompletedReconciliation(record)
                ? ".day-shift/prompts/user/reconciliation.review.md"
                : ".day-shift/prompts/user/reconciliation.build.md");
            return {
                artifactPath: record.path,
                artifactType: record.artifactType,
                recommendation: isCompletedReconciliation(record)
                    ? "Review reconciliation closure evidence."
                    : "Complete the milestone reconciliation.",
                reason: isCompletedReconciliation(record)
                    ? "The artifact is already in completed review state, so the next safe step is read-only closure validation."
                    : "The review artifact still carries incomplete state and should be finished before closure metadata is advanced.",
                command: record.upstreamMilestoneOverviewPath === null
                    ? null
                    : `node dist/cli/index.js reconciliation review --milestone-overview ${record.upstreamMilestoneOverviewPath}`,
                workflowPath: ".day-shift/workflows/04-summarize-and-reconcile.md",
                promptPath: promptResolution.resolvedPromptPath,
                promptResolution
            };
        }
        case "phase_overview": {
            const phaseReadyForReview = areAllDeclaredMilestonesReconciled(options.repositoryRoot, record);
            const promptResolution = resolveRequiredPromptReference(options.repositoryRoot, resolvedConfig.values, phaseReadyForReview
                ? ".day-shift/prompts/user/phase.review.md"
                : ".day-shift/prompts/user/phase.next.md");
            return {
                artifactPath: record.path,
                artifactType: record.artifactType,
                recommendation: phaseReadyForReview
                    ? "Review phase closure evidence."
                    : "Inspect milestone coverage beneath this phase.",
                reason: phaseReadyForReview
                    ? "Every declared milestone has completed reconciliation evidence; downstream evidence takes precedence over stale phase status for selecting the read-only review boundary."
                    : "The phase still has declared milestone work without completed reconciliation evidence.",
                command: phaseReadyForReview
                    ? `node dist/cli/index.js phase review --phase-overview ${record.path}`
                    : `node dist/cli/index.js planning inventory --root ${node_path_1.default.posix.dirname(record.path)}`,
                workflowPath: phaseReadyForReview
                    ? ".day-shift/workflows/04-summarize-and-reconcile.md"
                    : ".day-shift/workflows/02-plan-from-spec.md",
                promptPath: promptResolution.resolvedPromptPath,
                promptResolution
            };
        }
        case "slice_overview": {
            const promptResolution = resolveRequiredPromptReference(options.repositoryRoot, resolvedConfig.values, ".day-shift/prompts/user/slice.next.md");
            return {
                artifactPath: record.path,
                artifactType: record.artifactType,
                recommendation: "Inspect phase coverage beneath this slice.",
                reason: "Slice overviews stay on the planning boundary until a downstream phase, milestone, and task are selected.",
                command: `node dist/cli/index.js planning inventory --root ${node_path_1.default.posix.dirname(record.path)}`,
                workflowPath: ".day-shift/workflows/02-plan-from-spec.md",
                promptPath: promptResolution.resolvedPromptPath,
                promptResolution
            };
        }
        default:
            return assertNever(record.artifactType);
    }
}
function renderPlanningInventoryResult(result) {
    const lines = [
        (0, output_1.renderTerminalHeading)("Planning inventory", "title").trimEnd(),
        "",
        (0, output_1.renderTerminalSection)({
            heading: "Summary",
            fields: [
                { label: "Scope", value: result.scopePath },
                { label: "Scope kind", value: result.scopeKind },
                { label: "Slice overviews", value: result.sliceOverviewPaths.length },
                { label: "Phase overviews", value: result.phaseOverviewPaths.length },
                { label: "Milestone overviews", value: result.milestoneOverviewPaths.length },
                { label: "Task definitions", value: result.taskDefinitionPaths.length },
                { label: "Implementation summaries", value: result.implementationSummaryPaths.length },
                { label: "Reconciliations", value: result.reconciliationPaths.length }
            ],
            lines: [(0, output_1.renderTerminalBoundary)({ kind: "read-only" })]
        }),
        "",
        "Findings:"
    ];
    appendLines(lines, result.findings);
    return lines.join("\n");
}
function renderPlanningWorkCandidatesResult(result) {
    return [
        (0, output_1.renderTerminalHeading)("Planning work candidates", "title").trimEnd(),
        "",
        (0, output_1.renderTerminalSection)({
            heading: "Summary",
            fields: [
                { label: "Scope", value: result.scopePath },
                { label: "Scope kind", value: result.scopeKind },
                { label: "Candidates", value: result.totalCandidateCount },
                { label: "Returned", value: result.returnedCandidateCount },
                { label: "Omitted", value: result.omittedCandidateCount }
            ],
            lines: [
                "Candidate evidence is advisory. It does not select work or write selection state.",
                (0, output_1.renderTerminalBoundary)({ kind: "read-only" })
            ]
        }),
        "",
        (0, output_1.renderTerminalCompactList)({
            heading: "Candidates:",
            entries: result.candidates.map((candidate) => ({
                label: `${candidate.status}: ${candidate.artifactPath}`,
                fields: [
                    { label: "Artifact type", value: candidate.artifactType },
                    { label: "Observed state", value: candidate.observedState },
                    { label: "Selection command state", value: candidate.selectionCommandState }
                ],
                lines: [
                    ...candidate.reasons,
                    ...candidate.blockers.map((blocker) => `${blocker.code}: ${blocker.path} — ${blocker.message}`),
                    `Selection argv: ${JSON.stringify(candidate.selectionArgv)}`
                ]
            })),
            emptyMessage: "- (none)"
        })
    ].join("\n");
}
function renderPlanningGapReportResult(result) {
    const lines = [
        (0, output_1.renderTerminalHeading)("Planning gap report", "title").trimEnd(),
        "",
        (0, output_1.renderTerminalSection)({
            heading: "Summary",
            fields: [
                { label: "Scope", value: result.scopePath },
                { label: "Scope kind", value: result.scopeKind },
                { label: "Gaps", value: result.gaps.length }
            ],
            lines: [(0, output_1.renderTerminalBoundary)({ kind: "read-only" })]
        }),
        "",
        (0, output_1.renderTerminalCompactList)({
            heading: "Gaps:",
            entries: result.gaps.map((gap) => ({
                label: `${gap.code}: ${gap.path}`,
                lines: [gap.message]
            })),
            emptyMessage: "- (none)"
        })
    ];
    return lines.join("\n");
}
function renderWorkflowExplainResult(result) {
    return [
        (0, output_1.renderTerminalHeading)("Workflow explain", "title").trimEnd(),
        "",
        (0, output_1.renderTerminalSection)({
            heading: "Artifact",
            fields: [
                { label: "Path", value: result.artifactPath },
                { label: "Type", value: result.artifactType }
            ]
        }),
        "",
        (0, output_1.renderTerminalSection)({
            heading: "Workflow",
            fields: [
                { label: "Workflow", value: result.workflowPath },
                { label: "Prompt", value: result.promptPath ?? "(none)" },
                { label: "Prompt resolution", value: (0, config_layer_resolution_1.renderPromptResolutionSummary)(result.promptResolution) }
            ]
        }),
        "",
        (0, output_1.renderTerminalSection)({
            heading: "Guidance",
            fields: [
                { label: "Explanation", value: result.explanation },
                { label: "Recommendation", value: result.recommendation },
                { label: "Recommended command", value: result.recommendedCommand ?? "(workflow-guided step; no direct CLI command)" },
                { label: "Next boundary", value: result.nextBoundary }
            ],
            lines: [
                "Workflow guidance is advisory evidence only; it does not write files, mark tasks ready, complete implementation summaries, or update reconciliation.",
                (0, output_1.renderTerminalBoundary)({ kind: "read-only" }),
                (0, output_1.renderTerminalNextAction)({
                    command: result.recommendedCommand ?? result.workflowPath
                })
            ]
        })
    ].join("\n");
}
function renderPlanningNextActionResult(result) {
    return [
        (0, output_1.renderTerminalHeading)("Planning next action", "title").trimEnd(),
        "",
        (0, output_1.renderTerminalSection)({
            heading: "Summary",
            fields: [
                { label: "Artifact", value: result.artifactPath },
                { label: "Artifact type", value: result.artifactType },
                { label: "Recommendation", value: result.recommendation },
                { label: "Reason", value: result.reason },
                { label: "Command", value: result.command ?? "(workflow-guided step; no direct CLI command)" },
                { label: "Workflow", value: result.workflowPath ?? "(none)" },
                { label: "Prompt", value: result.promptPath ?? "(none)" },
                { label: "Prompt resolution", value: (0, config_layer_resolution_1.renderPromptResolutionSummary)(result.promptResolution) }
            ],
            lines: [
                (0, output_1.renderTerminalBoundary)({ kind: "read-only" }),
                (0, output_1.renderTerminalNextAction)({
                    command: result.command ?? result.workflowPath ?? "Use the reported workflow and prompt for the next manual step."
                })
            ]
        })
    ].join("\n");
}
function resolveRequiredPromptReference(repositoryRoot, config, requestedPromptPath) {
    return (0, config_layer_resolution_1.resolveRequiredPromptReference)({
        repositoryRoot,
        config,
        requestedPromptPath
    });
}
function resolveScope(repositoryRoot, inputPath, allowDirectory) {
    const parsedPath = (0, paths_1.parseRepositoryRelativePath)(inputPath);
    const absolutePath = (0, paths_1.resolveRepositoryRelativePath)(repositoryRoot, parsedPath);
    if (!node_fs_1.default.existsSync(absolutePath)) {
        throw (0, errors_1.createUsageError)(`Planning scope path '${parsedPath.normalizedPath}' does not exist.`, [
            "Pass an existing repository-relative planning path."
        ]);
    }
    const stats = node_fs_1.default.statSync(absolutePath);
    if (stats.isDirectory()) {
        if (!allowDirectory) {
            throw (0, errors_1.createUsageError)(`Artifact path '${parsedPath.normalizedPath}' must point to a planning artifact file.`, [
                "Use a repository-relative path to a slice/phase/milestone/task/review artifact."
            ]);
        }
        return {
            path: parsedPath.normalizedPath,
            absolutePath,
            kind: "planning-root"
        };
    }
    const record = readArtifactRecord(repositoryRoot, parsedPath.normalizedPath);
    return {
        path: parsedPath.normalizedPath,
        absolutePath,
        kind: record.artifactType
    };
}
function collectArtifactsForScope(repositoryRoot, scope) {
    if (scope.kind !== "planning-root") {
        return [readArtifactRecord(repositoryRoot, scope.path)];
    }
    const artifactPaths = [];
    const stack = [scope.absolutePath];
    while (stack.length > 0) {
        const currentPath = stack.pop();
        if (currentPath === undefined) {
            continue;
        }
        const stats = node_fs_1.default.statSync(currentPath);
        if (stats.isFile()) {
            const relativePath = (0, planning_document_utils_1.toRepositoryLikePath)(node_path_1.default.relative(repositoryRoot, currentPath));
            if (isRecognizedArtifactFilename(relativePath)) {
                artifactPaths.push(relativePath);
            }
            continue;
        }
        const children = node_fs_1.default.readdirSync(currentPath);
        for (const child of children) {
            stack.push(node_path_1.default.join(currentPath, child));
        }
    }
    return artifactPaths
        .sort((left, right) => left.localeCompare(right))
        .map((artifactPath) => readArtifactRecord(repositoryRoot, artifactPath));
}
function readArtifactRecord(repositoryRoot, artifactPath) {
    const absolutePath = (0, paths_1.resolveRepositoryRelativePath)(repositoryRoot, (0, paths_1.parseRepositoryRelativePath)(artifactPath));
    const document = parseMarkdownDocument(artifactPath, node_fs_1.default.readFileSync(absolutePath, "utf8"));
    const artifactType = (0, planning_document_utils_1.readTopLevelField)(document.frontMatterLines, "artifact_type")?.trim() ?? null;
    if (!isPlanningArtifactType(artifactType)) {
        throw (0, errors_1.createInvalidConfigError)(`Planning artifact '${artifactPath}' has unsupported artifact_type '${artifactType ?? "(missing)"}'.`, ["Expected a supported planning artifact with YAML front matter."]);
    }
    return {
        path: artifactPath,
        artifactType,
        status: (0, planning_document_utils_1.readTopLevelField)(document.frontMatterLines, "status")?.trim() ?? null,
        planningDepth: (0, planning_document_utils_1.readTopLevelField)(document.frontMatterLines, "planning_depth")?.trim() ?? null,
        readiness: (0, planning_document_utils_1.readTopLevelField)(document.frontMatterLines, "readiness")?.trim() ?? null,
        implementationStatus: (0, planning_document_utils_1.readTopLevelField)(document.frontMatterLines, "implementation_status")?.trim() ?? null,
        reconciliationStatus: (0, planning_document_utils_1.readTopLevelField)(document.frontMatterLines, "reconciliation_status")?.trim() ?? null,
        upstreamTaskDefinitionPath: (0, planning_document_utils_1.readUpstreamField)(document.frontMatterLines, "task_definition")?.trim() ?? null,
        upstreamMilestoneOverviewPath: (0, planning_document_utils_1.readUpstreamField)(document.frontMatterLines, "milestone_overview")?.trim() ?? null,
        document
    };
}
function readArtifactIfExists(repositoryRoot, artifactPath) {
    const absolutePath = (0, paths_1.resolveRepositoryRelativePath)(repositoryRoot, (0, paths_1.parseRepositoryRelativePath)(artifactPath));
    if (!node_fs_1.default.existsSync(absolutePath)) {
        return null;
    }
    return readArtifactRecord(repositoryRoot, artifactPath);
}
function collectArtifactGaps(repositoryRoot, record, gapMap) {
    switch (record.artifactType) {
        case "slice_overview":
            if (record.planningDepth === "lightweight") {
                collectLightweightTaskGaps(repositoryRoot, record, gapMap);
                return;
            }
            collectDeclaredChildGaps(repositoryRoot, record, "Phases", "phase_overview", gapMap);
            return;
        case "phase_overview":
            collectDeclaredChildGaps(repositoryRoot, record, "Milestones", "milestone_overview", gapMap);
            return;
        case "milestone_overview": {
            const reconciliationPath = pairedReconciliationPath(record.path);
            const reconciliationRecord = readArtifactIfExists(repositoryRoot, reconciliationPath);
            const allTaskSummariesComplete = areAllTaskImplementationSummariesComplete(repositoryRoot, record.path);
            if (allTaskSummariesComplete && reconciliationRecord === null) {
                addGap(gapMap, {
                    code: "MISSING_ARTIFACT",
                    path: reconciliationPath,
                    message: `Expected milestone reconciliation '${reconciliationPath}' is missing for '${record.path}'.`
                });
            }
            else if (allTaskSummariesComplete
                && reconciliationRecord !== null
                && !isCompletedReconciliation(reconciliationRecord)) {
                addGap(gapMap, {
                    code: "INCOMPLETE_ARTIFACT",
                    path: reconciliationPath,
                    message: `Milestone reconciliation '${reconciliationPath}' is present but still incomplete after all task implementation summaries are complete.`
                });
            }
            const taskSlugs = readDeclaredChildSlugsFromDocument(record.document, "Tasks");
            for (const taskSlug of taskSlugs) {
                const taskDefinitionPath = (0, planning_document_utils_1.toRepositoryLikePath)(node_path_1.default.posix.join(node_path_1.default.posix.dirname(record.path), "tasks", taskSlug, "task-definition.md"));
                const taskDirectory = (0, paths_1.resolveRepositoryRelativePath)(repositoryRoot, (0, paths_1.parseRepositoryRelativePath)(node_path_1.default.posix.dirname(taskDefinitionPath)));
                if (!node_fs_1.default.existsSync(taskDirectory)) {
                    continue;
                }
                const taskRecord = readArtifactIfExists(repositoryRoot, taskDefinitionPath);
                if (taskRecord === null) {
                    addGap(gapMap, {
                        code: "MISSING_ARTIFACT",
                        path: taskDefinitionPath,
                        message: `Declared task '${taskSlug}' is missing task definition '${taskDefinitionPath}'.`
                    });
                    continue;
                }
                collectArtifactGaps(repositoryRoot, taskRecord, gapMap);
            }
            return;
        }
        case "task_definition": {
            const taskIsClosed = isClosedTaskDefinition(record);
            const summaryPath = pairedImplementationSummaryPath(record.path);
            const summaryRecord = readArtifactIfExists(repositoryRoot, summaryPath);
            if (taskIsClosed && summaryRecord === null) {
                addGap(gapMap, {
                    code: "MISSING_ARTIFACT",
                    path: summaryPath,
                    message: `Expected implementation summary '${summaryPath}' is missing for task '${record.path}'.`
                });
                return;
            }
            if (taskIsClosed && summaryRecord !== null && !isCompletedImplementationSummary(summaryRecord)) {
                addGap(gapMap, {
                    code: "INCOMPLETE_ARTIFACT",
                    path: summaryPath,
                    message: `Implementation summary '${summaryPath}' is present but still incomplete.`
                });
            }
            if (summaryRecord !== null
                && isCompletedImplementationSummary(summaryRecord)
                && (record.status !== "completed" || record.readiness !== "completed")) {
                addGap(gapMap, {
                    code: "STALE_PAIRING",
                    path: record.path,
                    message: `Task definition '${record.path}' still needs closeout metadata after completed implementation evidence.`
                });
            }
            return;
        }
        case "implementation_summary":
            if (!isCompletedImplementationSummary(record)) {
                addGap(gapMap, {
                    code: "INCOMPLETE_ARTIFACT",
                    path: record.path,
                    message: `Implementation summary '${record.path}' still carries placeholder or incomplete execution evidence.`
                });
            }
            return;
        case "reconciliation":
            if (!isCompletedReconciliation(record)) {
                addGap(gapMap, {
                    code: "INCOMPLETE_ARTIFACT",
                    path: record.path,
                    message: `Reconciliation '${record.path}' still carries placeholder or incomplete review evidence.`
                });
            }
            return;
        default:
            return assertNever(record.artifactType);
    }
}
function collectLightweightTaskGaps(repositoryRoot, sliceRecord, gapMap) {
    const tasksDirectory = (0, paths_1.resolveRepositoryRelativePath)(repositoryRoot, (0, paths_1.parseRepositoryRelativePath)((0, planning_document_utils_1.toRepositoryLikePath)(node_path_1.default.posix.join(node_path_1.default.posix.dirname(sliceRecord.path), "tasks"))));
    if (!node_fs_1.default.existsSync(tasksDirectory)) {
        return;
    }
    const taskSlugs = node_fs_1.default.readdirSync(tasksDirectory).sort((left, right) => left.localeCompare(right));
    for (const taskSlug of taskSlugs) {
        const taskDefinitionPath = (0, planning_document_utils_1.toRepositoryLikePath)(node_path_1.default.posix.join(node_path_1.default.posix.dirname(sliceRecord.path), "tasks", taskSlug, "task-definition.md"));
        const taskRecord = readArtifactIfExists(repositoryRoot, taskDefinitionPath);
        if (taskRecord === null) {
            addGap(gapMap, {
                code: "MISSING_ARTIFACT",
                path: taskDefinitionPath,
                message: `Lightweight task directory '${taskSlug}' is missing task definition '${taskDefinitionPath}'.`
            });
            continue;
        }
        collectArtifactGaps(repositoryRoot, taskRecord, gapMap);
    }
}
function collectDeclaredChildGaps(repositoryRoot, record, sectionName, childArtifactType, gapMap) {
    const childSlugs = readDeclaredChildSlugsFromDocument(record.document, sectionName);
    const childDirectoryName = sectionName === "Phases" ? "phases" : "milestones";
    const childLayer = childArtifactType === "phase_overview" ? "phase" : "milestone";
    for (const childSlug of childSlugs) {
        const childDirectoryPath = (0, planning_document_utils_1.toRepositoryLikePath)(node_path_1.default.posix.join(node_path_1.default.posix.dirname(record.path), childDirectoryName, childSlug));
        const childDirectory = (0, paths_1.resolveRepositoryRelativePath)(repositoryRoot, (0, paths_1.parseRepositoryRelativePath)(childDirectoryPath));
        if (!node_fs_1.default.existsSync(childDirectory)) {
            continue;
        }
        const childResolution = (0, paths_1.resolvePlanningOverviewPath)(repositoryRoot, {
            layer: childLayer,
            directoryPath: childDirectoryPath
        });
        const childOverviewPath = childResolution.selected?.path
            ?? (0, paths_1.composeCanonicalPlanningOverviewPath)(childLayer, childDirectoryPath);
        const childRecord = childResolution.selected === null
            ? null
            : readArtifactIfExists(repositoryRoot, childOverviewPath);
        if (childResolution.status === "conflict") {
            addGap(gapMap, {
                code: "PATH_CONFLICT",
                path: childOverviewPath,
                message: childResolution.message
            });
            continue;
        }
        if (childRecord === null) {
            addGap(gapMap, {
                code: "MISSING_ARTIFACT",
                path: childOverviewPath,
                message: `Declared ${childArtifactType === "phase_overview" ? "phase" : "milestone"} '${childSlug}' is missing overview '${childOverviewPath}'.`
            });
            continue;
        }
        collectArtifactGaps(repositoryRoot, childRecord, gapMap);
    }
}
function collectTaskSummariesForMilestone(repositoryRoot, milestoneOverviewPath) {
    const taskDirectory = (0, paths_1.resolveRepositoryRelativePath)(repositoryRoot, (0, paths_1.parseRepositoryRelativePath)((0, planning_document_utils_1.toRepositoryLikePath)(node_path_1.default.posix.join(node_path_1.default.posix.dirname(milestoneOverviewPath), "tasks"))));
    if (!node_fs_1.default.existsSync(taskDirectory)) {
        return [];
    }
    const summaries = [];
    const taskChildren = node_fs_1.default.readdirSync(taskDirectory);
    for (const taskSlug of taskChildren) {
        const summaryPath = (0, planning_document_utils_1.toRepositoryLikePath)(node_path_1.default.posix.join(node_path_1.default.posix.dirname(milestoneOverviewPath), "tasks", taskSlug, "implementation-summary.md"));
        const summaryRecord = readArtifactIfExists(repositoryRoot, summaryPath);
        if (summaryRecord !== null) {
            summaries.push(summaryRecord);
        }
    }
    return summaries.sort((left, right) => left.path.localeCompare(right.path));
}
function areAllKnownTaskImplementationSummariesCompleteForMilestone(taskDefinitions, summaries, milestoneOverviewPath) {
    const taskPathPrefix = `${node_path_1.default.posix.dirname(milestoneOverviewPath)}/tasks/`;
    const taskRecords = taskDefinitions.filter((record) => record.path.startsWith(taskPathPrefix));
    if (taskRecords.length === 0) {
        return false;
    }
    return taskRecords.every((taskRecord) => {
        const summaryPath = pairedImplementationSummaryPath(taskRecord.path);
        const summaryRecord = summaries.find((record) => record.path === summaryPath) ?? null;
        return summaryRecord !== null && isCompletedImplementationSummary(summaryRecord);
    });
}
function areAllTaskImplementationSummariesComplete(repositoryRoot, milestoneOverviewPath) {
    const taskDirectory = (0, paths_1.resolveRepositoryRelativePath)(repositoryRoot, (0, paths_1.parseRepositoryRelativePath)((0, planning_document_utils_1.toRepositoryLikePath)(node_path_1.default.posix.join(node_path_1.default.posix.dirname(milestoneOverviewPath), "tasks"))));
    if (!node_fs_1.default.existsSync(taskDirectory)) {
        return false;
    }
    const taskChildren = node_fs_1.default.readdirSync(taskDirectory)
        .filter((taskSlug) => node_fs_1.default.statSync(node_path_1.default.join(taskDirectory, taskSlug)).isDirectory());
    if (taskChildren.length === 0) {
        return false;
    }
    return taskChildren.every((taskSlug) => {
        const summaryPath = (0, planning_document_utils_1.toRepositoryLikePath)(node_path_1.default.posix.join(node_path_1.default.posix.dirname(milestoneOverviewPath), "tasks", taskSlug, "implementation-summary.md"));
        const summaryRecord = readArtifactIfExists(repositoryRoot, summaryPath);
        return summaryRecord !== null && isCompletedImplementationSummary(summaryRecord);
    });
}
function areAllDeclaredMilestonesReconciled(repositoryRoot, phaseRecord) {
    const milestoneSlugs = readDeclaredChildSlugsFromDocument(phaseRecord.document, "Milestones");
    if (milestoneSlugs.length === 0)
        return false;
    return milestoneSlugs.every((milestoneSlug) => {
        const milestoneDirectoryPath = (0, planning_document_utils_1.toRepositoryLikePath)(node_path_1.default.posix.join(node_path_1.default.posix.dirname(phaseRecord.path), "milestones", milestoneSlug));
        const resolution = (0, paths_1.resolvePlanningOverviewPath)(repositoryRoot, {
            layer: "milestone",
            directoryPath: milestoneDirectoryPath
        });
        if (resolution.status === "conflict" || resolution.selected === null)
            return false;
        const reconciliationRecord = readArtifactIfExists(repositoryRoot, pairedReconciliationPath(resolution.selected.path));
        return reconciliationRecord !== null && isCompletedReconciliation(reconciliationRecord);
    });
}
function groupArtifacts(records) {
    return {
        sliceOverviewPaths: records.filter((record) => record.artifactType === "slice_overview"),
        phaseOverviewPaths: records.filter((record) => record.artifactType === "phase_overview"),
        milestoneOverviewPaths: records.filter((record) => record.artifactType === "milestone_overview"),
        taskDefinitionPaths: records.filter((record) => record.artifactType === "task_definition"),
        implementationSummaryPaths: records.filter((record) => record.artifactType === "implementation_summary"),
        reconciliationPaths: records.filter((record) => record.artifactType === "reconciliation")
    };
}
function isSelectablePlanningRecord(record) {
    return record.artifactType === "slice_overview"
        || record.artifactType === "phase_overview"
        || record.artifactType === "milestone_overview"
        || record.artifactType === "task_definition";
}
function isPlanningRecordCompleted(repositoryRoot, record) {
    switch (record.artifactType) {
        case "task_definition": {
            const summary = readArtifactIfExists(repositoryRoot, pairedImplementationSummaryPath(record.path));
            return summary !== null && isCompletedImplementationSummary(summary);
        }
        case "milestone_overview": {
            const reconciliation = readArtifactIfExists(repositoryRoot, pairedReconciliationPath(record.path));
            return reconciliation !== null && isCompletedReconciliation(reconciliation);
        }
        case "phase_overview":
            return areAllDeclaredMilestonesReconciled(repositoryRoot, record);
        case "slice_overview":
            return record.status === "completed";
        default:
            return false;
    }
}
function isPlanningDescendant(candidatePath, ancestorPath) {
    return candidatePath.startsWith(`${node_path_1.default.posix.dirname(ancestorPath)}/`);
}
function buildPlanningWorkCandidate(repositoryRoot, record, selectableRecords) {
    const blockers = [
        ...collectPriorSiblingBlockers(repositoryRoot, record, selectableRecords),
        ...collectDependencyBlockers(repositoryRoot, record)
    ];
    const actionable = blockers.length === 0;
    return {
        artifactPath: record.path,
        artifactType: record.artifactType,
        observedState: planningCandidateObservedState(repositoryRoot, record),
        status: actionable ? "actionable" : "blocked",
        reasons: [planningCandidateReason(record.artifactType, actionable)],
        blockers,
        selectionArgv: ["day-shift", "work", "select", "--artifact", record.path],
        selectionCommandState: "callable"
    };
}
function collectPriorSiblingBlockers(repositoryRoot, record, selectableRecords) {
    const siblingRoot = node_path_1.default.posix.dirname(node_path_1.default.posix.dirname(record.path));
    const priorIncompleteSibling = selectableRecords.find((candidate) => candidate.artifactType === record.artifactType
        && node_path_1.default.posix.dirname(node_path_1.default.posix.dirname(candidate.path)) === siblingRoot
        && candidate.path.localeCompare(record.path) < 0
        && !isPlanningRecordCompleted(repositoryRoot, candidate));
    return priorIncompleteSibling === undefined
        ? []
        : [{
                code: "PRIOR_SIBLING_INCOMPLETE",
                path: priorIncompleteSibling.path,
                message: `Earlier declared ${record.artifactType} work is incomplete.`
            }];
}
function collectDependencyBlockers(repositoryRoot, record) {
    const dependencySection = record.document.sections.get("Dependencies") ?? "";
    const dependencyPaths = extractRepositoryRelativeDependencyPaths(dependencySection);
    const blockers = [];
    for (const dependencyPath of dependencyPaths) {
        const absolutePath = (0, paths_1.resolveRepositoryRelativePath)(repositoryRoot, (0, paths_1.parseRepositoryRelativePath)(dependencyPath));
        if (!node_fs_1.default.existsSync(absolutePath)) {
            blockers.push({
                code: "DEPENDENCY_MISSING",
                path: dependencyPath,
                message: "Declared dependency does not exist."
            });
            continue;
        }
        if (!isCompletionEvidencePath(dependencyPath)) {
            continue;
        }
        const dependencyRecord = readArtifactRecord(repositoryRoot, dependencyPath);
        const completed = dependencyRecord.artifactType === "implementation_summary"
            ? isCompletedImplementationSummary(dependencyRecord)
            : dependencyRecord.artifactType === "reconciliation"
                ? isCompletedReconciliation(dependencyRecord)
                : isClosedTaskDefinition(dependencyRecord);
        if (!completed) {
            blockers.push({
                code: "DEPENDENCY_INCOMPLETE",
                path: dependencyPath,
                message: "Declared lifecycle dependency is present but incomplete."
            });
        }
    }
    return blockers;
}
function extractRepositoryRelativeDependencyPaths(sectionText) {
    const paths = new Set();
    for (const line of sectionText.split(/\r?\n/)) {
        const match = line.match(/(?:^|[\s`(])((?:\.day-shift|src|tests_v2|schemas|scripts|apps)\/[^\s`)]+)/);
        if (match !== null) {
            paths.add(match[1].replace(/[.,;:]$/, ""));
        }
    }
    return [...paths];
}
function isCompletionEvidencePath(dependencyPath) {
    return dependencyPath.endsWith("/implementation-summary.md")
        || dependencyPath.endsWith("/reconciliation.md")
        || dependencyPath.endsWith("/task-definition.md");
}
function planningCandidateObservedState(repositoryRoot, record) {
    switch (record.artifactType) {
        case "task_definition":
            return record.readiness ?? record.status ?? "unknown";
        case "milestone_overview":
            return areAllTaskImplementationSummariesComplete(repositoryRoot, record.path)
                ? "ready-for-reconciliation"
                : "tasks-pending";
        case "phase_overview":
            return "milestones-pending";
        case "slice_overview":
            return "phases-pending";
        default:
            return "unknown";
    }
}
function planningCandidateReason(artifactType, actionable) {
    if (!actionable) {
        return "Canonical planning work is incomplete but cannot advance until the reported blockers are resolved.";
    }
    switch (artifactType) {
        case "task_definition":
            return "Task is the next incomplete declared implementation unit in its milestone.";
        case "milestone_overview":
            return "Milestone is the next incomplete declared checkpoint in its phase.";
        case "phase_overview":
            return "Phase is the next incomplete declared work group in its slice.";
        case "slice_overview":
            return "Slice contains incomplete declared planning work.";
    }
}
function pickGapAnalysisRoots(records) {
    const grouped = groupArtifacts(records);
    if (grouped.sliceOverviewPaths.length > 0) {
        return grouped.sliceOverviewPaths;
    }
    if (grouped.phaseOverviewPaths.length > 0) {
        return grouped.phaseOverviewPaths;
    }
    if (grouped.milestoneOverviewPaths.length > 0) {
        return grouped.milestoneOverviewPaths;
    }
    if (grouped.taskDefinitionPaths.length > 0) {
        return grouped.taskDefinitionPaths;
    }
    if (grouped.implementationSummaryPaths.length > 0) {
        return grouped.implementationSummaryPaths;
    }
    return grouped.reconciliationPaths;
}
function parseMarkdownDocument(filePath, rawText) {
    const parsed = (0, planning_artifact_document_1.parsePlanningArtifactDocument)(rawText);
    if (!parsed.hasFrontMatter) {
        const malformed = parsed.diagnostics.some((diagnostic) => diagnostic.code === "unterminated-front-matter");
        if (malformed) {
            throw (0, errors_1.createInvalidConfigError)(`Planning artifact '${filePath}' has malformed YAML front matter.`, [
                "Expected a closing front-matter fence."
            ]);
        }
        throw (0, errors_1.createInvalidConfigError)(`Planning artifact '${filePath}' is missing YAML front matter.`, [
            "Expected the document to start with a front-matter fence."
        ]);
    }
    const sections = new Map();
    for (const section of parsed.sections) {
        sections.set(section.heading, section.contentText.trim());
    }
    return {
        frontMatterLines: parsed.frontMatterLines,
        sections,
        rawText
    };
}
function readDeclaredChildSlugsFromDocument(document, sectionName) {
    const sectionText = document.sections.get(sectionName);
    return sectionText === undefined ? [] : (0, planning_document_utils_1.readDeclaredChildSlugs)(sectionText);
}
function pairedImplementationSummaryPath(taskDefinitionPath) {
    return (0, planning_document_utils_1.toRepositoryLikePath)(node_path_1.default.posix.join(node_path_1.default.posix.dirname(taskDefinitionPath), "implementation-summary.md"));
}
function pairedReconciliationPath(milestoneOverviewPath) {
    return (0, planning_document_utils_1.toRepositoryLikePath)(node_path_1.default.posix.join(node_path_1.default.posix.dirname(milestoneOverviewPath), "reconciliation.md"));
}
function isCompletedImplementationSummary(record) {
    return record.artifactType === "implementation_summary"
        && record.implementationStatus === "completed"
        && record.status === "completed"
        && !hasPlaceholderContent(record.document.rawText, INCOMPLETE_SUMMARY_PHRASES);
}
function isClosedTaskDefinition(record) {
    return (0, artifact_lifecycle_1.isCompletedTaskLifecycle)(record);
}
function isCompletedReconciliation(record) {
    return record.artifactType === "reconciliation"
        && record.reconciliationStatus === "completed"
        && record.status === "completed"
        && !hasPlaceholderContent(record.document.rawText, INCOMPLETE_RECONCILIATION_PHRASES);
}
function hasPlaceholderContent(rawText, incompletePhrases) {
    if (PLACEHOLDER_PATTERN.test(rawText)) {
        return true;
    }
    return incompletePhrases.some((phrase) => rawText.includes(phrase));
}
function addGap(gapMap, gap) {
    if (!gapMap.has(gap.path)) {
        gapMap.set(gap.path, gap);
    }
}
function appendLines(lines, entries) {
    if (entries.length === 0) {
        lines.push("- (none)");
        return;
    }
    for (const entry of entries) {
        lines.push(`- ${entry}`);
    }
}
function isRecognizedArtifactFilename(relativePath) {
    return relativePath.endsWith("/overview.md")
        || relativePath.endsWith("/slice-overview.md")
        || relativePath.endsWith("/phase-overview.md")
        || relativePath.endsWith("/milestone-overview.md")
        || relativePath.endsWith("/task-definition.md")
        || relativePath.endsWith("/implementation-summary.md")
        || relativePath.endsWith("/reconciliation.md")
        || relativePath === "overview.md"
        || relativePath === "slice-overview.md"
        || relativePath === "phase-overview.md"
        || relativePath === "milestone-overview.md"
        || relativePath === "task-definition.md"
        || relativePath === "implementation-summary.md"
        || relativePath === "reconciliation.md";
}
function isPlanningArtifactType(value) {
    return value === "slice_overview"
        || value === "phase_overview"
        || value === "milestone_overview"
        || value === "task_definition"
        || value === "implementation_summary"
        || value === "reconciliation";
}
function assertNever(value) {
    throw new Error(`Unexpected value: ${String(value)}`);
}
