"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createSliceWorkspace = createSliceWorkspace;
exports.allocateGovernedSliceDestination = allocateGovernedSliceDestination;
exports.routeContributorsToGovernedSlice = routeContributorsToGovernedSlice;
const node_crypto_1 = require("node:crypto");
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const cli_constants_1 = require("../config/cli-constants");
const errors_1 = require("../errors");
const command_write_summary_1 = require("../license/command-write-summary");
const paths_1 = require("../paths");
const spec_registry_1 = require("../spec-registry");
const authoring_policy_1 = require("./authoring-policy");
const front_matter_utils_1 = require("./front-matter-utils");
const governed_hierarchy_context_1 = require("./governed-hierarchy-context");
const scaffold_application_1 = require("./scaffold-application");
const upstream_specs_1 = require("./upstream-specs");
const workflow_provenance_1 = require("./workflow-provenance");
const IMPLEMENTATION_ORDER_PATTERN = /^(?:0\d|[1-9]\d+)$/u;
const ORDERED_SLICE_ID_PATTERN = /^((?:0\d|[1-9]\d+))-([a-z0-9]+(?:-[a-z0-9]+)*)$/u;
function createSliceWorkspace(repositoryRoot, selection) {
    assertSelection(selection);
    const specIndexPath = node_path_1.default.join(repositoryRoot, '.day-shift', 'specs', 'index.json');
    const specIndexText = node_fs_1.default.readFileSync(specIndexPath, 'utf8');
    const specIndex = parseSliceSpecIndex(specIndexText);
    const resolved = resolveSelection(specIndex.entries, selection);
    const allocation = allocateGovernedSliceDestination({
        entries: specIndex.entries,
        selectedSpecIds: resolved.contributors.map((entry) => entry.id),
        requestedSliceId: selection.sliceId,
        existingSliceIds: collectExistingGovernedSliceIds(repositoryRoot),
        includeCompatibleContributors: true,
    });
    const implementationOrder = allocation.implementationOrder;
    const sliceSlug = allocation.sliceSlug;
    const orderedSliceDirectoryName = allocation.sliceId;
    const governedSliceOverviewRelativePath = node_path_1.default.posix.join('.day-shift/planning/governed', orderedSliceDirectoryName, 'slice-overview.md');
    const governedSliceOverviewPath = node_path_1.default.join(repositoryRoot, governedSliceOverviewRelativePath);
    const routedSpecIndex = routeContributorsToGovernedSlice(specIndex, allocation.contributors, implementationOrder, sliceSlug, orderedSliceDirectoryName, governedSliceOverviewRelativePath);
    const routedContributors = allocation.contributors.map((entry) => {
        const routed = routedSpecIndex.entries.find((candidate) => candidate.id === entry.id);
        if (routed === undefined) {
            throw new Error(`Routed spec index lost contributor '${entry.id}'.`);
        }
        return routed;
    });
    const governedContext = node_fs_1.default.existsSync(governedSliceOverviewPath)
        ? (0, governed_hierarchy_context_1.readGovernedSliceOverviewSync)(repositoryRoot, governedSliceOverviewRelativePath, routedContributors.map((entry) => ({ id: entry.id, path: entry.spec_path })))
        : null;
    const sliceDirectoryPath = node_path_1.default.dirname(governedSliceOverviewPath);
    const sliceDirectoryRelativePath = (0, front_matter_utils_1.toRepositoryLikePath)(node_path_1.default.relative(repositoryRoot, sliceDirectoryPath));
    const overviewRelativePath = governedContext?.sliceOverviewPath ?? (0, paths_1.composeCanonicalPlanningOverviewPath)('slice', sliceDirectoryRelativePath);
    const overviewPath = node_path_1.default.join(repositoryRoot, overviewRelativePath);
    const decisionsDirectoryPath = node_path_1.default.join(sliceDirectoryPath, 'decisions');
    const notesDirectoryPath = node_path_1.default.join(sliceDirectoryPath, 'notes');
    const decisionsGitkeepPath = node_path_1.default.join(decisionsDirectoryPath, '.gitkeep');
    const notesGitkeepPath = node_path_1.default.join(notesDirectoryPath, '.gitkeep');
    const overviewExists = node_fs_1.default.existsSync(overviewPath);
    const overviewText = overviewExists
        ? null
        : renderSliceOverviewMarkdown({
            repositoryRoot,
            sliceSlug,
            contributors: routedContributors,
            implementationOrder,
            governedSliceId: orderedSliceDirectoryName,
            sliceDirectoryRelativePath,
            selectedSelector: selection.specId?.trim() !== ''
                ? buildSliceSelector(`--spec-id ${resolved.selected.id}`)
                : buildSliceSelector(`--slice-id ${resolved.selectedSliceId}`),
        });
    const decisionsGitkeepExists = node_fs_1.default.existsSync(decisionsGitkeepPath);
    const notesGitkeepExists = node_fs_1.default.existsSync(notesGitkeepPath);
    const routedSpecIndexContents = (0, spec_registry_1.renderSpecIndexDocument)(routedSpecIndex);
    const specIndexChanged = resolved.contributors.some((entry) => {
        const routed = routedContributors.find((candidate) => candidate.id === entry.id);
        return (routed === undefined ||
            entry.depth !== routed.depth ||
            entry.destination !== routed.destination ||
            entry.optional.linked_slice?.slice !== routed.optional.linked_slice?.slice ||
            entry.optional.linked_slice?.path !== routed.optional.linked_slice?.path);
    });
    const plannedWrites = [
        ...(!overviewExists && overviewText !== null ? [{ path: overviewRelativePath, contents: overviewText }] : []),
        ...(!decisionsGitkeepExists
            ? [
                {
                    path: (0, front_matter_utils_1.toRepositoryLikePath)(node_path_1.default.relative(repositoryRoot, decisionsGitkeepPath)),
                    contents: '',
                },
            ]
            : []),
        ...(!notesGitkeepExists
            ? [
                {
                    path: (0, front_matter_utils_1.toRepositoryLikePath)(node_path_1.default.relative(repositoryRoot, notesGitkeepPath)),
                    contents: '',
                },
            ]
            : []),
        ...(specIndexChanged
            ? [
                {
                    path: (0, front_matter_utils_1.toRepositoryLikePath)(node_path_1.default.relative(repositoryRoot, specIndexPath)),
                    contents: routedSpecIndexContents,
                    mode: 'replace',
                    expectedRevision: (0, scaffold_application_1.planningScaffoldContentRevision)(specIndexText),
                },
            ]
            : []),
    ];
    const application = selection.dryRun === true
        ? {
            outcome: 'no-write',
            intendedPaths: plannedWrites.map((write) => write.path),
            changedPaths: [],
            transactionId: null,
            conflicts: [],
            recoveryPath: null,
            failure: null,
        }
        : (0, scaffold_application_1.applyPlanningScaffoldSync)(repositoryRoot, plannedWrites, {
            parentPaths: governedContext === null ? [] : [governedContext.sliceOverviewPath],
        });
    if (selection.dryRun !== true) {
        (0, scaffold_application_1.assertPlanningScaffoldApplied)(application);
    }
    return {
        repositoryRoot,
        specIndexPath,
        implementationOrder,
        sliceSlug,
        orderedSliceDirectoryName,
        sliceDirectoryPath,
        overviewPath,
        decisionsGitkeepPath,
        notesGitkeepPath,
        selectedSpecId: resolved.selected.id,
        selectedSliceId: resolved.selectedSliceId,
        contributingSpecIds: allocation.contributors.map((entry) => entry.id),
        workflowLevel: governedContext?.workflowLevel ?? 'governed',
        canonicalSliceId: governedContext?.sliceId ?? orderedSliceDirectoryName,
        dryRun: selection.dryRun === true,
        overviewAction: overviewExists ? 'kept' : selection.dryRun === true ? 'would-create' : 'created',
        decisionsGitkeepAction: decisionsGitkeepExists ? 'kept' : selection.dryRun === true ? 'would-create' : 'created',
        notesGitkeepAction: notesGitkeepExists ? 'kept' : selection.dryRun === true ? 'would-create' : 'created',
        registryAction: specIndexChanged ? selection.dryRun === true ? 'would-link' : 'linked' : 'kept',
        requiresRefinement: true,
        application,
        commandWriteSummary: (0, command_write_summary_1.normalizeCommandWriteSummary)({
            commandFamily: 'slice_generation',
            dryRun: selection.dryRun === true,
            primaryOutputArtifacts: [(0, front_matter_utils_1.toRepositoryLikePath)(node_path_1.default.relative(repositoryRoot, overviewPath))],
            updatedArtifacts: [
                {
                    path: (0, front_matter_utils_1.toRepositoryLikePath)(node_path_1.default.relative(repositoryRoot, overviewPath)),
                    action: overviewExists ? 'kept' : 'created',
                    reason: overviewExists ? 'no_write' : selection.dryRun === true ? 'dry_run' : 'accepted_create',
                },
                ...(specIndexChanged
                    ? [
                        {
                            path: (0, front_matter_utils_1.toRepositoryLikePath)(node_path_1.default.relative(repositoryRoot, specIndexPath)),
                            action: 'changed',
                            reason: selection.dryRun === true ? 'dry_run' : 'accepted_content_change',
                        },
                    ]
                    : []),
            ],
        }),
    };
}
function allocateGovernedSliceDestination(input) {
    if (!Array.isArray(input.selectedSpecIds) || input.selectedSpecIds.length === 0) {
        throw (0, errors_1.createUsageError)('Governed destination allocation requires at least one selected spec.');
    }
    const selectedIds = new Set(input.selectedSpecIds);
    if (selectedIds.size !== input.selectedSpecIds.length) {
        throw (0, errors_1.createUsageError)('Governed destination allocation received duplicate selected spec ids.');
    }
    const selected = input.selectedSpecIds.map((specId) => {
        const entry = input.entries.find((candidate) => candidate.id === specId);
        if (entry === undefined) {
            throw (0, errors_1.createUsageError)(`Unknown spec id '${specId}'.`);
        }
        return entry;
    });
    const linkedSliceIds = distinctNonEmpty(selected.map((entry) => entry.optional.linked_slice?.slice));
    if (linkedSliceIds.length > 1) {
        throw (0, errors_1.createUsageError)('Selected slice contributors have conflicting linked_slice identities.', linkedSliceIds.map((value) => `linked_slice.slice: ${value}`));
    }
    const linkedSliceId = linkedSliceIds[0] ?? null;
    const requestedSliceId = normalizeOptionalOrderedSliceId(input.requestedSliceId);
    const orderEvidence = distinctNonEmpty([
        ...selected.map((entry) => normalizeImplementationOrderValue(entry.optional.implementation_order)),
        linkedSliceId === null ? '' : splitOrderedSliceId(linkedSliceId).implementationOrder,
    ]);
    if (orderEvidence.length > 1) {
        throw (0, errors_1.createUsageError)('Selected slice context has conflicting implementation orders.', orderEvidence.map((value) => `implementation_order: ${value}`));
    }
    const implementationOrder = orderEvidence[0] ??
        (requestedSliceId === null
            ? allocateNextImplementationOrder(input.entries, input.existingSliceIds ?? [])
            : splitOrderedSliceId(requestedSliceId).implementationOrder);
    if (!IMPLEMENTATION_ORDER_PATTERN.test(implementationOrder)) {
        throw (0, errors_1.createUsageError)(`implementation_order '${implementationOrder}' is not a canonical ordered prefix.`, [
            'Use 00 for emergent intake or a positive whole number rendered with at least two digits.',
        ]);
    }
    const slugEvidence = distinctNonEmpty([
        ...selected.map((entry) => resolveEntrySliceSlug(entry, implementationOrder)),
        linkedSliceId === null ? '' : splitOrderedSliceId(linkedSliceId).sliceSlug,
    ]);
    if (slugEvidence.length > 1) {
        throw (0, errors_1.createUsageError)('Selected slice contributors resolve to conflicting slice slugs.', slugEvidence.map((value) => `slice_slug: ${value}`));
    }
    const fallbackSlug = selected.length === 1 ? normalizeSliceSlug(selected[0].id, selected[0].id) : null;
    const sliceSlug = slugEvidence[0] ?? (requestedSliceId === null ? fallbackSlug : splitOrderedSliceId(requestedSliceId).sliceSlug);
    if (sliceSlug === null) {
        throw (0, errors_1.createUsageError)('Multiple unrouted specifications do not provide one canonical governed slice slug.', [
            'Supply compatible destination metadata or select one specification at a time.',
        ]);
    }
    const orderedSlugResult = (0, paths_1.composeOrderedSlugName)(implementationOrder, sliceSlug);
    if (orderedSlugResult.kind !== 'ordered-slug-name') {
        throw (0, errors_1.createUsageError)('Could not compose ordered slice directory name from selected spec context.', [
            orderedSlugResult.reason.message,
        ]);
    }
    const sliceId = orderedSlugResult.orderedSlugName;
    if (linkedSliceId !== null && linkedSliceId !== sliceId) {
        throw (0, errors_1.createUsageError)(`Existing linked_slice identity '${linkedSliceId}' conflicts with canonical destination '${sliceId}'.`);
    }
    if (requestedSliceId !== null && requestedSliceId !== sliceId) {
        throw (0, errors_1.createUsageError)(`Requested Governed slice identity '${requestedSliceId}' conflicts with explicit order and slug evidence; expected '${sliceId}'.`);
    }
    const compatibleContributors = [...selected];
    for (const entry of input.entries) {
        if (selectedIds.has(entry.id) || entry.status.trim().toLowerCase() === 'archived') {
            continue;
        }
        const entryOrder = resolveEntryImplementationOrder(entry);
        if (entryOrder !== implementationOrder)
            continue;
        const entrySlug = resolveEntrySliceSlug(entry, implementationOrder);
        if (entrySlug !== sliceSlug) {
            throw (0, errors_1.createUsageError)(`implementation_order '${implementationOrder}' collides with contributor '${entry.id}'.`, [
                `Expected slice slug '${sliceSlug}' but observed '${entrySlug ?? 'unresolved'}'.`,
            ]);
        }
        if (input.includeCompatibleContributors === true) {
            compatibleContributors.push(entry);
        }
    }
    const existingSliceIds = new Set(input.existingSliceIds ?? []);
    for (const existingSliceId of existingSliceIds) {
        const normalized = normalizeOptionalOrderedSliceId(existingSliceId);
        if (normalized === null)
            continue;
        if (splitOrderedSliceId(normalized).implementationOrder === implementationOrder && normalized !== sliceId) {
            throw (0, errors_1.createUsageError)(`implementation_order '${implementationOrder}' collides with existing Governed slice '${normalized}'.`);
        }
    }
    const preserved = linkedSliceId === sliceId;
    if (existingSliceIds.has(sliceId) && !preserved) {
        throw (0, errors_1.createUsageError)(`Governed slice identity '${sliceId}' is already in use.`);
    }
    return {
        implementationOrder,
        sliceSlug,
        sliceId,
        generated: requestedSliceId === null && !preserved,
        preserved,
        contributors: compatibleContributors,
    };
}
function assertSelection(selection) {
    const hasSpecId = typeof selection.specId === 'string' && selection.specId.trim() !== '';
    const hasSliceId = typeof selection.sliceId === 'string' && selection.sliceId.trim() !== '';
    if (hasSpecId && hasSliceId) {
        throw (0, errors_1.createUsageError)('Provide either --spec-id or --slice-id, not both.');
    }
    if (!hasSpecId && !hasSliceId) {
        throw (0, errors_1.createUsageError)('Provide selection context via --spec-id or --slice-id.', [
            'Example: day-shift slice new --spec-id planning-artifacts-artifact-model',
        ]);
    }
}
function resolveSelection(entries, selection) {
    if (selection.specId !== undefined && selection.specId.trim() !== '') {
        const selected = entries.find((entry) => entry.id === selection.specId?.trim());
        if (selected === undefined) {
            throw (0, errors_1.createUsageError)(`Unknown spec id '${selection.specId}'.`);
        }
        const selectedSliceId = resolveSelectedSliceId(selected);
        if (selected.optional.linked_slice !== undefined) {
            const contributors = entries.filter((entry) => {
                const linked = entry.optional.linked_slice;
                return linked !== undefined && linked.slice === selected.optional.linked_slice?.slice;
            });
            return {
                selected,
                selectedSliceId,
                contributors: contributors.length > 0 ? contributors : [selected],
            };
        }
        const selectedOrder = normalizeImplementationOrderValue(selected.optional.implementation_order);
        const selectedDestinationHead = selected.destination?.split('/')[0];
        const contributors = selected.destination === undefined
            ? [selected]
            : entries.filter((entry) => {
                return (entry.optional.linked_slice === undefined &&
                    entry.status.trim().toLowerCase() !== 'archived' &&
                    entry.destination?.split('/')[0] === selectedDestinationHead &&
                    normalizeImplementationOrderValue(entry.optional.implementation_order) === selectedOrder);
            });
        return {
            selected,
            selectedSliceId,
            contributors: contributors.length > 0 ? contributors : [selected],
        };
    }
    const requestedSliceId = selection.sliceId?.trim() ?? '';
    const contributors = entries.filter((entry) => entry.optional.linked_slice?.slice === requestedSliceId);
    if (contributors.length === 0) {
        throw (0, errors_1.createUsageError)(`No registered specs found for slice '${requestedSliceId}'.`, [
            `When using --slice-id, the value must match linked_slice.slice in ${cli_constants_1.CLI_SPEC_INDEX_PATH}.`,
        ]);
    }
    return {
        selected: contributors[0],
        selectedSliceId: requestedSliceId,
        contributors,
    };
}
function resolveSelectedSliceId(entry) {
    if (entry.optional.linked_slice !== undefined) {
        return entry.optional.linked_slice.slice;
    }
    if (entry.destination === undefined)
        return entry.id;
    const destinationHead = entry.destination.split('/')[0];
    const normalized = (0, paths_1.normalizeCanonicalSlug)(destinationHead);
    if (normalized.kind === 'canonical-slug') {
        return normalized.normalizedSlug;
    }
    throw (0, errors_1.createUsageError)(`Spec '${entry.id}' does not have linked_slice metadata and destination '${entry.destination}' cannot be normalized into a canonical slice slug.`, [normalized.reason.message]);
}
function normalizeImplementationOrderValue(value) {
    if (typeof value === 'string')
        return value.trim();
    if (typeof value === 'number' && Number.isSafeInteger(value) && value >= 0) {
        return String(value).padStart(2, '0');
    }
    return '';
}
function parseSliceSpecIndex(contents) {
    try {
        return (0, spec_registry_1.parseSpecIndexDocumentText)(contents);
    }
    catch (error) {
        throw (0, errors_1.createUsageError)('Could not parse spec registry for slice selection.', [
            error instanceof Error ? error.message : String(error),
        ]);
    }
}
function routeContributorsToGovernedSlice(document, contributors, implementationOrder, sliceSlug, sliceId, sliceOverviewPath) {
    const contributorIds = new Set(contributors.map((entry) => entry.id));
    const nextEntries = document.entries.map((entry) => {
        if (!contributorIds.has(entry.id))
            return entry;
        return (0, spec_registry_1.parseSpecIndexEntry)({
            ...(0, spec_registry_1.serializeSpecIndexEntry)(entry),
            depth: entry.depth ?? 'standard',
            destination: entry.destination ?? sliceSlug,
            implementation_order: entry.optional.implementation_order ?? implementationOrder,
            linked_slice: {
                slice: sliceId,
                path: sliceOverviewPath,
            },
        });
    });
    const planningDepths = new Set(nextEntries.filter((entry) => contributorIds.has(entry.id)).map((entry) => entry.depth));
    if (planningDepths.size !== 1) {
        throw (0, errors_1.createUsageError)('Selected slice contributors have conflicting planning depths.', [...planningDepths].map((depth) => `depth: ${String(depth)}`));
    }
    return (0, spec_registry_1.buildSpecIndexDocumentWithEntries)(document, nextEntries);
}
function resolveEntryImplementationOrder(entry) {
    const explicit = normalizeImplementationOrderValue(entry.optional.implementation_order);
    if (explicit !== '')
        return explicit;
    const linked = entry.optional.linked_slice?.slice ?? '';
    const parsed = ORDERED_SLICE_ID_PATTERN.exec(linked);
    return parsed === null ? null : parsed[1];
}
function resolveEntrySliceSlug(entry, implementationOrder) {
    const linked = entry.optional.linked_slice?.slice;
    if (typeof linked === 'string' && linked.startsWith(`${implementationOrder}-`)) {
        return normalizeSliceSlug(linked.slice(implementationOrder.length + 1), entry.id);
    }
    const emergent = resolveDedicatedEmergentSliceSlug({
        implementationOrder,
        selected: entry,
    });
    if (emergent !== null)
        return emergent;
    if (entry.destination === undefined)
        return null;
    return normalizeSliceSlug(entry.destination.split('/')[0], entry.id);
}
function normalizeSliceSlug(value, specId) {
    if ((0, paths_1.isCanonicalSlug)(value))
        return value;
    const normalized = (0, paths_1.normalizeCanonicalSlug)(value);
    if (normalized.kind === 'canonical-slug')
        return normalized.normalizedSlug;
    throw (0, errors_1.createUsageError)(`Spec '${specId}' does not resolve to a canonical slice slug.`, [normalized.reason.message]);
}
function normalizeOptionalOrderedSliceId(value) {
    if (value === undefined || value === null || value.trim() === '')
        return null;
    const normalized = value.trim();
    if (!ORDERED_SLICE_ID_PATTERN.test(normalized)) {
        throw (0, errors_1.createUsageError)(`Governed slice identity '${normalized}' must match '<ordered-prefix>-<slice-slug>' with an order of at least two digits.`);
    }
    return normalized;
}
function splitOrderedSliceId(value) {
    const match = ORDERED_SLICE_ID_PATTERN.exec(value);
    if (match === null) {
        throw (0, errors_1.createUsageError)(`Governed slice identity '${value}' is not canonical.`);
    }
    return { implementationOrder: match[1], sliceSlug: match[2] };
}
function allocateNextImplementationOrder(entries, existingSliceIds) {
    const occupied = new Set();
    for (const entry of entries) {
        const order = resolveEntryImplementationOrder(entry);
        if (order !== null && IMPLEMENTATION_ORDER_PATTERN.test(order))
            occupied.add(Number(order));
    }
    for (const sliceId of existingSliceIds) {
        const parsed = ORDERED_SLICE_ID_PATTERN.exec(sliceId);
        if (parsed !== null)
            occupied.add(Number(parsed[1]));
    }
    for (let candidate = 1; Number.isSafeInteger(candidate); candidate += 1) {
        if (!occupied.has(candidate))
            return String(candidate).padStart(2, '0');
    }
    throw (0, errors_1.createUsageError)('No unused Governed implementation order is available within the supported integer range.');
}
function collectExistingGovernedSliceIds(repositoryRoot) {
    const root = node_path_1.default.join(repositoryRoot, '.day-shift', 'planning', 'governed');
    if (!node_fs_1.default.existsSync(root))
        return [];
    if (!node_fs_1.default.statSync(root).isDirectory()) {
        throw (0, errors_1.createUsageError)('Governed planning root is not a directory.');
    }
    return node_fs_1.default
        .readdirSync(root, { withFileTypes: true })
        .filter((entry) => entry.isDirectory())
        .map((entry) => entry.name);
}
function distinctNonEmpty(values) {
    return [
        ...new Set(values
            .filter((value) => typeof value === 'string' && value.trim() !== '')
            .map((value) => value.trim())),
    ];
}
function resolveDedicatedEmergentSliceSlug(options) {
    if (options.implementationOrder !== '00') {
        return null;
    }
    if (options.selected.destination === undefined) {
        return null;
    }
    if (!options.selected.destination.startsWith('emergent/')) {
        return null;
    }
    const specPathValue = (0, paths_1.parseRepositoryRelativePath)(options.selected.spec_path);
    const isActiveEmergentSpec = specPathValue.segments[0] === '.day-shift' &&
        specPathValue.segments[1] === 'specs' &&
        specPathValue.segments[2] === '00-emergent';
    if (!isActiveEmergentSpec) {
        return null;
    }
    const destinationSlug = options.selected.destination.slice('emergent/'.length);
    if (!(0, paths_1.isCanonicalSlug)(destinationSlug)) {
        throw (0, errors_1.createUsageError)(`Emergent destination '${options.selected.destination}' cannot be used as a canonical slice slug.`, ['Use destination: emergent/<slug> with lowercase letters, numbers, and hyphen-separated segments.']);
    }
    return `emergent-${destinationSlug}`;
}
function renderSliceOverviewMarkdown(options) {
    const title = (0, front_matter_utils_1.toTitleCase)(options.sliceSlug);
    const workflowProvenance = (0, workflow_provenance_1.buildCliWorkflowProvenance)(options.selectedSelector);
    const sourcePaths = options.contributors.map((entry) => `- ${entry.spec_path}`).join('\n');
    const contributorList = options.contributors.map((entry) => `- ${entry.id}`).join('\n');
    const upstreamSpecs = options.contributors
        .map((entry) => {
        const upstreamEntry = (0, upstream_specs_1.createUpstreamSpecEntryFromSpecIndex)(entry);
        const specificationBytes = node_fs_1.default.readFileSync(node_path_1.default.resolve(options.repositoryRoot, upstreamEntry.ref));
        const revision = `sha256:${(0, node_crypto_1.createHash)('sha256').update(specificationBytes).digest('hex')}`;
        return [
            `    - id: ${upstreamEntry.id}`,
            `      depth: ${upstreamEntry.depth}`,
            `      ref: ${JSON.stringify(upstreamEntry.ref)}`,
            `      source_type: ${JSON.stringify(upstreamEntry.sourceType)}`,
            `      revision: ${JSON.stringify(revision)}`,
        ].join('\n');
    })
        .join('\n');
    const text = [
        '---',
        'artifact_schema_version: 1',
        'artifact_type: slice_overview',
        `slice: ${options.governedSliceId ?? options.sliceSlug}`,
        ...(options.governedSliceId === null
            ? []
            : [
                `implementation_order: ${JSON.stringify(options.implementationOrder)}`,
                'workflow_level: governed',
                'default_agent_mode: ""',
                'default_evidence_profile: ""',
            ]),
        `planning_depth: ${options.contributors[0].depth}`,
        `workflow_provenance: ${workflowProvenance.workflowProvenance}`,
        `workflow_cli_command: ${JSON.stringify(workflowProvenance.workflowCliCommand)}`,
        'status: draft',
        'upstream:',
        '  specs:',
        upstreamSpecs,
        '---',
        '',
        `# ${title}`,
        '',
        '## Purpose',
        '',
        `Document the ${options.sliceSlug} planning slice from registered spec context so downstream phase and milestone planning can proceed consistently.`,
        '',
        '## Source Specification',
        '',
        'This slice overview is derived from:',
        sourcePaths,
        '',
        '## Desired Outcome',
        '',
        `A stable planning root exists at ${options.sliceDirectoryRelativePath}/ with deterministic slice-level traceability.`,
        '',
        '## Scope',
        '',
        '- Preserve one ordered planning root for the selected slice context.',
        '- Preserve list-based upstream traceability for all contributing source specs.',
        '- Keep slice-level structure ready for phase planning.',
        '',
        '## Non-Goals',
        '',
        '- Implement phase, milestone, or task artifacts during slice generation.',
        '- Expand to undeclared child artifacts.',
        '',
        '## Planning Depth',
        '',
        options.contributors[0].depth,
        '',
        '## Phases',
        '',
        '- To be planned.',
        '',
        '## Decisions',
        '',
        '- This slice was generated from registered spec context.',
        '- Contributing specs:',
        contributorList,
        '',
        '## Risks',
        '',
        '- Follow-on updates should keep slice-generation guidance and executable behavior aligned.',
        '',
        '## Validation Strategy',
        '',
        '- Validate metadata and path contracts with standard CLI checks.',
        '',
        '## Open Questions',
        '',
        '- None currently.',
        '',
    ].join('\n');
    assertPlanningAuthoringCompliance('slice_overview', text);
    return text;
}
function buildSliceSelector(selectionArgument) {
    return `day-shift slice new ${selectionArgument}`;
}
function assertPlanningAuthoringCompliance(artifactType, markdownText) {
    const issues = (0, authoring_policy_1.auditPlanningArtifactAuthoring)({
        artifactPath: 'generated slice overview',
        artifactType,
        markdownText,
    });
    if (issues.length > 0) {
        throw (0, errors_1.createUsageError)(`Planning authoring policy rejected generated ${artifactType} scaffold text.`, (0, authoring_policy_1.formatPlanningAuthoringIssues)(issues));
    }
}
