"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WORKFLOW_PLAN_RULES = void 0;
exports.buildWorkerDecisionRules = buildWorkerDecisionRules;
const types_1 = require("./types");
const workflow_continuation_guidance_1 = require("./workflow-continuation-guidance");
const workflow_planning_fields_1 = require("./workflow-planning-fields");
const workflow_selection_fields_1 = require("./workflow-selection-fields");
const workflow_surface_1 = require("./workflow-surface");
exports.WORKFLOW_PLAN_RULES = {
    topLevelFields: `Keep mode-allowed planning contract fields at the decision top level: ${(0, workflow_planning_fields_1.formatWorkflowPlanningFieldList)(workflow_planning_fields_1.WORKFLOW_PLANNING_TOP_LEVEL_FIELD_NAMES)}. Omit fields that are disallowed for the current planning intent, and do not copy them into step instructions or doneWhen.`,
    issueTitle: "Set `issueTitle` to a short list-visible title for the planned issue. Include only the central work name; do not include recurring prefixes, timestamps, parent issue suffixes, or executable first-line /alpaca command text.",
    noAdministrativeSteps: "Do not create plan steps for writing decision JSON, posting comments, final summaries, approvals, issue closing, label changes, pull request handling, publishing, or other control-plane bookkeeping.",
    executionGuidance: "Generate `executionGuidance` as short issue-wide constraints that apply to every execution step.",
    executionGuidanceContent: "Include only durable shared handoff, notification, side-effect, evidence, forbidden-shortcut, and reference-document rules in `executionGuidance`. Put step order, final-only checks, step-specific, planning-only, selection-only, current-run, and prompt-only instructions on the relevant plan step or omit them.",
    persistedArtifactSources: "Derive persisted planning fields only from issue body, human instructions, workflow template body, command context, workflow state facts, and workspace evidence.",
    persistedArtifactExclusions: "Do not copy prompt scaffolding into persisted planning fields. Exclude mode-only instructions, current-run restrictions, JSON/schema/example rules, repair hints, and control-plane mechanics.",
    priorityRank: "For planning or replanning runs, return `priorityRank` as a semantic planning field. It must be `null` or a non-negative safe integer. Smaller values run earlier; use sparse integers; if unsure, use `2000`.",
    predictedTouchedPaths: "Define `predictedTouchedPaths` as the minimum set of repo-tracked files that must be directly edited to complete the issue.",
    predictedTouchedPathsFinal: "For generated drafts, dry-run candidates, or reviewed normalizations, `predictedTouchedPaths` must list the final repo-tracked path that should be edited after normalization, not the temporary draft path or an unreviewed candidate.",
    followupSeed: "When the request asks for independent post-completion iteration or improvement, plan a clear doneWhen boundary for the current issue and describe enough evidence for workflow_closing to distinguish current-scope completion from independent follow-up work. Do not use follow-up for unresolved current doneWhen, broad unfinished goals, or downstream phases still required by the broad goal contract; do not use replan_same_issue or child_issue for independent post-completion improvements.",
    childIssueDelegation: "Use child_issue steps when parent-blocking work has its own objective, outputs, completion checks, and at least one separate-tracking reason: independent deliverable, evidence bundle, review or integration boundary, materially different responsibility area, or likely multiple AI cycles.",
};
const NEEDS_HUMAN_QUESTION_COMMENT_RULE = "For needsHumanReason=question, result.humanComment must state the exact needed decision/info, recommended response, realistic alternative, relevant URLs, credential cautions, and checked or unavailable evidence. Use bullets for multiple reply items.";
const GENERATED_TEXT_CONTEXT_RULE = "Human-visible or future-context text must be readable and operationally useful: state concrete outcomes/evidence/decisions/actions in user/domain terms; keep needed commands, paths, issue refs, API/schema names, versions, and technical terms; avoid routine control-plane bookkeeping, workflow-state fields, revisions, cursors, or internal enums unless the task is about them; never be generic.";
function buildWorkerDecisionRules(workflow) {
    const rules = [
        "Return exactly one JSON object in the decision block.",
        "outcome must be one of proceed, wait_human, fail.",
        "result is required.",
        "result.resultSummary is required and short; result.humanComment is an optional human-facing issue comment for questions, stop reasons, or visible notes.",
        GENERATED_TEXT_CONTEXT_RULE,
        "commitMessage must be a string or null when provided.",
    ];
    if (!workflow) {
        rules.push("If no workflow context is provided, omit the workflow object.");
        return rules;
    }
    if (workflow.mode === types_1.WORKER_RUN_MODES.workflowSelect) {
        appendWorkflowSelectRules(rules, workflow);
        return rules;
    }
    rules.push(`workflow.mode must be ${workflow.mode}.`, `workflow.templateName must be ${JSON.stringify(workflow.templateName)}.`, "The workflow object must contain only mode and templateName.");
    if (workflow.mode === types_1.WORKER_RUN_MODES.workflowExecute) {
        appendWorkflowExecuteRules(rules);
        return rules;
    }
    if (workflow.mode === types_1.WORKER_RUN_MODES.workflowReconcileStepBatch) {
        appendWorkflowStepBatchReconciliationRules(rules);
        return rules;
    }
    if (workflow.mode === types_1.WORKER_RUN_MODES.workflowClosing) {
        appendWorkflowClosingRules(rules, workflow);
        return rules;
    }
    appendWorkflowPlanRules(rules, workflow);
    return rules;
}
function appendWorkflowSelectRules(rules, workflow) {
    const selectionContext = workflow.selection ?? null;
    rules.push("workflow_select rules apply only to workflow template selection for the active workflow surface.", "workflow.selection is the authoritative selection context.", "Do not let prompt scaffolding, JSON/schema/example rules, planning instructions, or execute instructions influence the selected template.", "selection is required for proceed decisions.", "Do not return plan or contract.", "Return selection.action before any planning work begins.", "Use selection.action=use_template with selection.templateName when a listed or explicit template should be used.", "Use selection.action=no_template when planning should continue with the built-in default workflow instead of a listed repository-specific template.", "Use selection.action=request_template only when workflow.selection.templateSlot is auto and a reusable workflow template is needed but no suitable template is available.", "Choose use_template when a candidate template clearly matches the work class and would provide useful reusable sequencing, judgment, safety checks, or coordination guidance without narrowing or contradicting the issue.", "Choose no_template for simple, one-off, or ordinary work where no repository-specific candidate adds useful reusable guidance beyond the built-in default workflow.", "Choose request_template only when reusable workflow guidance would materially improve safety, consistency, repeatability, or required coordination for this class of work, no candidate template fits that class, and the slot is auto.", "Slots marked auto or auto_select require selection.action to be returned explicitly.", "Slots marked deterministic are explicit locks; preserve their explicit template values exactly.", `workflow.mode must be ${workflow.mode}.`, `workflow.templateName must be ${JSON.stringify(workflow.templateName)}.`, "The workflow object must contain only mode and templateName.");
    appendAutoSelectionRules(rules, selectionContext);
    appendExplicitSelectionRules(rules, selectionContext);
    appendCandidateSelectionRules(rules, selectionContext);
}
function appendAutoSelectionRules(rules, selectionContext) {
    for (const spec of workflow_selection_fields_1.ACTIVE_WORKFLOW_SELECTION_FIELD_SPECS) {
        appendAutoSelectionRule(rules, {
            slotName: spec.slotField,
            slotMode: (0, workflow_selection_fields_1.getActiveWorkflowSelectionSlotMode)(selectionContext),
            actionFieldName: spec.actionField,
        });
    }
}
function appendAutoSelectionRule(rules, input) {
    if (input.slotMode !== "auto" && input.slotMode !== "auto_select") {
        return;
    }
    rules.push(`selection.${input.actionFieldName} is required because workflow.selection.${input.slotName} is ${input.slotMode}.`);
}
function appendExplicitSelectionRules(rules, selectionContext) {
    for (const spec of workflow_selection_fields_1.ACTIVE_WORKFLOW_SELECTION_FIELD_SPECS) {
        const explicitTemplateName = (0, workflow_selection_fields_1.getActiveWorkflowSelectionExplicitTemplateName)(selectionContext);
        if (explicitTemplateName !== undefined) {
            if (explicitTemplateName === null) {
                rules.push(`selection.${spec.actionField} must be ${types_1.WORKER_WORKFLOW_SELECTION_ACTIONS.noTemplate} because workflow.selection.${spec.explicitField} is null.`);
            }
            else {
                rules.push(`selection.${spec.actionField} must be ${types_1.WORKER_WORKFLOW_SELECTION_ACTIONS.useTemplate} and selection.${spec.selectionField} must be ${JSON.stringify(explicitTemplateName)} because workflow.selection.${spec.explicitField} is provided.`);
            }
        }
    }
}
function appendCandidateSelectionRules(rules, selectionContext) {
    for (const spec of workflow_selection_fields_1.ACTIVE_WORKFLOW_SELECTION_FIELD_SPECS) {
        appendCandidateSelectionRule(rules, {
            spec,
            candidates: (0, workflow_selection_fields_1.getActiveWorkflowSelectionCandidates)(selectionContext) ?? null,
            explicitTemplateName: (0, workflow_selection_fields_1.getActiveWorkflowSelectionExplicitTemplateName)(selectionContext),
            slotMode: (0, workflow_selection_fields_1.getActiveWorkflowSelectionSlotMode)(selectionContext),
        });
    }
}
function appendCandidateSelectionRule(inputRules, input) {
    if (input.explicitTemplateName !== undefined) {
        return;
    }
    const candidates = input.candidates ?? null;
    if (candidates === null) {
        return;
    }
    if (candidates.length > 0) {
        inputRules.push(`When selection.action is ${types_1.WORKER_WORKFLOW_SELECTION_ACTIONS.useTemplate}, selection.templateName must be one of: ${candidates.map((candidate) => candidate.templateName).join(", ")}.`);
        return;
    }
    inputRules.push(input.slotMode === "auto"
        ? `selection.action must be ${types_1.WORKER_WORKFLOW_SELECTION_ACTIONS.noTemplate} or ${types_1.WORKER_WORKFLOW_SELECTION_ACTIONS.requestTemplate} when no candidate workflow templates are provided.`
        : `selection.action must be ${types_1.WORKER_WORKFLOW_SELECTION_ACTIONS.noTemplate} when no candidate workflow templates are provided.`);
}
function appendWorkflowExecuteRules(rules) {
    rules.push("workflow_execute rules apply only to executing the current workflow step.", "Always include the workflow object in the decision JSON.", "Do not return workflow.state or other control-plane-owned fields.", "Return only workflow plus semantic top-level fields: result, commitMessage, needsHumanReason, continuation.", "Do not return priorityRank or other planning-only fields.", "Do not treat prompt scaffolding, JSON/schema/example rules, mode-only instructions, or control-plane mechanics as issue requirements, blockers, or completion evidence.", workflow_continuation_guidance_1.WORKFLOW_CONTINUATION_GUIDANCE.inspectableUnknowns, workflow_continuation_guidance_1.WORKFLOW_CONTINUATION_GUIDANCE.executeInspectableUnknowns, workflow_continuation_guidance_1.WORKFLOW_CONTINUATION_GUIDANCE.humanJudgmentBoundary, "When the current step is complete and no human review is required, return proceed.", "Do not use needsHumanReason=review_ready during workflow_execute; final human review is decided during workflow_closing.", "continuation is only allowed when outcome is proceed.", "If continuation is present, continuation.reason is required; continuation.title is required only for continuation.strategy=spawn_child_issue.", "Do not return followupRecommendation during workflow_execute; final follow-up recommendation is decided during workflow_closing.", "For proceed, result.evidence must be non-empty and map to current step doneWhen; result.humanComment is not evidence.", workflow_continuation_guidance_1.WORKFLOW_CONTINUATION_GUIDANCE.finalStepBoundary, "commitMessage is null/omitted without commit-worthy changes; otherwise it is one short subject matching the diff.", `wait_human and fail decisions must include the human-facing reason in result.humanComment. ${NEEDS_HUMAN_QUESTION_COMMENT_RULE}`, workflow_continuation_guidance_1.WORKFLOW_CONTINUATION_GUIDANCE.replanSameIssue, workflow_continuation_guidance_1.WORKFLOW_CONTINUATION_GUIDANCE.spawnChildIssue);
}
function appendWorkflowStepBatchReconciliationRules(rules) {
    rules.push("workflow_reconcile_step_batch rules apply to an already-run parallel workflow step batch only.", "Inspect the combined workspace diff and worker results for the active step batch.", "Do not execute unrelated ready steps, future dependent steps, workflow_ref expansion, or child_issue materialization.", "Fix conflicting or clobbered changes when the correct combined result is inspectable.", "Return stepResults with exactly one result for every active batch step.", "Each proceed stepResult must include evidence that maps to that step's doneWhen.", "Do not mark a step proceed from workerResults alone; use evidence from the reconciled workspace, command output, or another observable state.", "Run focused verification when feasible, or explain the blocker or limitation in result evidence or humanComment.", "Inspect workerResults continuation values before deciding the final batch result.", "remainingIncompleteSteps are already planned downstream work; do not return continuation or replan only because those steps are not finished yet.", "The top-level outcome must match stepResults: fail if any step failed, wait_human if any step needs human input, otherwise proceed.", "Return continuation only when the final reconciled outcome is proceed and the combined batch requires same-issue replanning or a separately tracked child issue.", "Do not return followupRecommendation during workflow_reconcile_step_batch; final follow-up recommendation is decided during workflow_closing.", "Do not use needsHumanReason=review_ready during workflow_reconcile_step_batch; final human review is decided during workflow_closing.", "commitMessage is null/omitted without commit-worthy changes; otherwise it is one short subject matching the reconciled diff.", "Do not return plan, contract, priorityRank, or selection.", "Use wait_human when the correct combined result cannot be determined safely.");
}
function appendWorkflowClosingRules(rules, workflow) {
    rules.push("workflow_closing rules apply only to the final issue-level completion audit before the source issue is closed.", "Do not edit files, create commits, push branches, close issues, edit labels, create PRs, publish comments, or perform control-plane side effects.", "Always include the workflow object in the decision JSON.", "Do not return workflow.state or other control-plane-owned fields.", "Return only workflow plus semantic top-level fields: result, commitMessage, needsHumanReason, continuation, followupRecommendation.", "Do not return stepResults, plan, contract, priorityRank, selection, executionGuidance, predictedTouchedPaths, or workflowStartApproval.", "Compare the latest user instruction, original issue, execution contract, plan step results, completed evidence, and current source issue state before deciding completion.", "If issue-level doneWhen is unmet, evidence is insufficient, or a broad goal contract still requires downstream phases, do not close through follow-up. Use continuation.strategy=replan_same_issue for same-issue plan changes, continuation.strategy=spawn_child_issue for independently trackable blockers, wait_human(question) for human judgment, or fail for unrecoverable failure.", "If the source issue is complete and final human review is required, return wait_human with needsHumanReason=review_ready unless workflow.issueCompletion.target is pull_request.", "If the source issue is complete and no human review is required, return proceed.", "For proceed, result.evidence must name issue-level completion evidence, not just the final step activity.", "continuation is only allowed when outcome is proceed.", "If continuation is present, continuation.reason is required; continuation.title is required only for continuation.strategy=spawn_child_issue.", "For followupRecommendation, consider only same source issue post-completion work. Do not aggregate or recreate follow-up items generated inside child issues.");
    const followup = workflow.state?.followup;
    if (followup !== undefined && followup.proposalPolicy !== "off") {
        rules.push("When returning proceed, include followupRecommendation with recommended, reason, and items.");
        switch (followup.proposalApproval) {
            case "confirm":
                rules.push("For followupRecommendation, first identify independent post-completion follow-up candidates from the source issue, merge candidates with the same purpose, deliverable, or verification evidence, classify each item.category as mainWork or maintenance, then return all useful candidates ordered by value and independence. The followup.maxIssuesPerSource limits do not cap candidates that will wait for human confirmation. Keep each item.body concise. Optional item.workflowTemplate may be a follow-up template path or no_template only.");
                break;
            case "confirm_if_needed":
                rules.push("For followupRecommendation, first identify independent post-completion follow-up candidates from the source issue, merge candidates with the same purpose, deliverable, or verification evidence, classify each item.category as mainWork or maintenance, then set item.proposalApproval to auto only for clearly necessary candidates and confirm for uncertain candidates. Items without proposalApproval are treated as confirm. The followup.maxIssuesPerSource limits cap only auto items; confirm items should still be returned for human review. Keep each item.body concise. Optional item.workflowTemplate may be a follow-up template path or no_template only.");
                break;
            case "auto":
                rules.push("For followupRecommendation, first identify independent post-completion follow-up candidates from the source issue, merge candidates with the same purpose, deliverable, or verification evidence, classify each item.category as mainWork or maintenance, then return at most followup.maxIssuesPerSource.mainWork mainWork items and followup.maxIssuesPerSource.maintenance maintenance items ordered by value and independence. Keep each item.body concise. Optional item.workflowTemplate may be a follow-up template path or no_template only.");
                break;
        }
    }
    else {
        rules.push("Omit followupRecommendation unless workflow.state.followup.proposalPolicy is not off.");
    }
    if (workflow.workflowSurface === "issue" &&
        workflow.issueCompletion?.target === "pull_request") {
        rules.push("With workflow.issueCompletion.target=pull_request, do not use needsHumanReason=review_ready on the source issue. When the source issue is complete, return proceed.");
    }
}
function appendWorkflowPlanRules(rules, workflow) {
    const isIncrementalReplan = workflow.planningIntent === "replan" ||
        workflow.planningIntent === "revise_plan";
    rules.push("workflow_plan rules apply only to producing or revising the executable workflow plan.", "Include the workflow object in the decision JSON.", isIncrementalReplan
        ? workflow_planning_fields_1.WORKFLOW_REPLANNING_REQUIRED_PROCEED_RULE
        : workflow_planning_fields_1.WORKFLOW_PLANNING_REQUIRED_PROCEED_RULE, exports.WORKFLOW_PLAN_RULES.topLevelFields, exports.WORKFLOW_PLAN_RULES.noAdministrativeSteps, exports.WORKFLOW_PLAN_RULES.persistedArtifactSources, exports.WORKFLOW_PLAN_RULES.persistedArtifactExclusions, workflow_continuation_guidance_1.WORKFLOW_CONTINUATION_GUIDANCE.inspectableUnknowns, workflow_continuation_guidance_1.WORKFLOW_CONTINUATION_GUIDANCE.planInspectableUnknowns, workflow_continuation_guidance_1.WORKFLOW_CONTINUATION_GUIDANCE.humanJudgmentBoundary, `Do not use needsHumanReason=review_ready. Planning must either return proceed with the required planning output for this intent or wait_human for an unresolved human-only question after accessible sources are inspected. ${NEEDS_HUMAN_QUESTION_COMMENT_RULE}`);
    if (isIncrementalReplan) {
        appendWorkflowReplanPatchRules(rules, workflow);
        appendWorkflowStartApprovalRules(rules, workflow);
        return;
    }
    rules.push(exports.WORKFLOW_PLAN_RULES.issueTitle, exports.WORKFLOW_PLAN_RULES.executionGuidance, exports.WORKFLOW_PLAN_RULES.executionGuidanceContent, "On proceed, the plan object must contain only steps.", (0, workflow_surface_1.isIssueWorkflowSurface)(workflow)
        ? "Each plan step must set kind explicitly to task, workflow_ref, or child_issue."
        : "Each plan step must set kind explicitly to task or workflow_ref.", (0, workflow_surface_1.isIssueWorkflowSurface)(workflow)
        ? "Use task steps for same-issue work, workflow_ref steps for same-issue nested workflow expansion, and child_issue steps for parent-blocking work with its own objective, outputs, completion checks, and at least one separate-tracking reason such as independent deliverable, evidence bundle, review or integration boundary, materially different responsibility area, or likely multiple AI cycles."
        : "Use task steps for same-thread work and workflow_ref steps for same-surface nested workflow expansion.", "Each plan step must include dependsOnStepIds, using an empty array when the step has no dependencies.", "Each doneWhen item must name observable evidence, such as command result, file or API state, tracker dependency, or child issue result.", exports.WORKFLOW_PLAN_RULES.predictedTouchedPaths, exports.WORKFLOW_PLAN_RULES.predictedTouchedPathsFinal, exports.WORKFLOW_PLAN_RULES.followupSeed, "Task steps must omit targetTemplateName, callSiteId, sourceTemplateName, sourceTemplateDigest, and expansionGroupId.", ...((0, workflow_surface_1.isIssueWorkflowSurface)(workflow)
        ? [
            exports.WORKFLOW_PLAN_RULES.childIssueDelegation,
            workflow_continuation_guidance_1.WORKFLOW_CONTINUATION_GUIDANCE.humanHandoffBoundary,
            "Each child_issue step must include childKey, inputs, and outputs.",
            "childKey values must be unique within child_issue plan steps.",
        ]
        : [
            "Do not use child_issue steps on pull_request, unplanned, merge, or follow-up workflow surfaces.",
        ]), "For workflow_ref metadata, use only the control-plane-provided direct child workflow call sites listed in workflow context.", "Do not infer callSiteId or expansionGroupId from template prose, template body text, links, or unreached child or grandchild template bodies.", "workflow_ref metadata must stay flat on the step object. Do not invent nested objects such as workflowRef or alternate key names.", exports.WORKFLOW_PLAN_RULES.priorityRank);
    appendWorkflowStartApprovalRules(rules, workflow);
    if ((workflow.directChildWorkflows?.length ?? 0) > 0) {
        rules.push("When direct child workflow call sites are listed, emit exactly one workflow_ref step for each listed call site and preserve their order.", "Each workflow_ref step must include a human-facing title plus non-empty targetTemplateName, callSiteId, sourceTemplateName, sourceTemplateDigest, and expansionGroupId.");
    }
}
function appendWorkflowReplanPatchRules(rules, workflow) {
    rules.push("Return planPatch only for incremental plan changes; do not return a full plan object.", "Omit unchanged steps and unchanged planning metadata. If issueTitle, contract, executionGuidance, predictedTouchedPaths, or priorityRank are returned, treat them as changed metadata only.", "For planPatch.stepChanges add_step or update_step entries, each provided step must include dependsOnStepIds, using an empty array when the step has no dependencies.", "For planPatch.stepChanges add_step or update_step entries, each doneWhen item must name observable evidence, such as command result, file or API state, tracker dependency, or child issue result.", (0, workflow_surface_1.isIssueWorkflowSurface)(workflow)
        ? "For planPatch.stepChanges add_step or update_step entries, each step must set kind explicitly to task, workflow_ref, or child_issue."
        : "For planPatch.stepChanges add_step or update_step entries, each step must set kind explicitly to task or workflow_ref.", "Use update_step for incomplete same-issue task steps or for parent child_issue contract changes. If a materialized child has not started, the control plane can patch the child issue; if it has started, pair the parent child_issue update with queue_child_issue_replan, or return wait_human when automatic reconciliation is unsafe.", "Use add_step with replacementForStepIds when new work replaces completed evidence; do not delete or overwrite completed results.", "Use remove_step only for incomplete steps with no durable side effects. Materialized children require detach_child_issue or cancel_child_issue plus remove_step.", "Use move_step only when the existing incomplete task or unmaterialized child_issue step contents and dependencies stay unchanged and only its list position changes. If execution order semantics must change, use update_step.dependsOnStepIds.", "Use workflowRefChanges refresh_workflow_ref or remove_workflow_ref instead of update_step for workflow_ref control-plane metadata or expansion changes.", "For workflow_ref metadata, use only control-plane-provided callSiteId, expansionGroupId, originSubtreeKey, and source template identity.", exports.WORKFLOW_PLAN_RULES.followupSeed, exports.WORKFLOW_PLAN_RULES.childIssueDelegation, workflow_continuation_guidance_1.WORKFLOW_CONTINUATION_GUIDANCE.humanHandoffBoundary);
}
function appendWorkflowStartApprovalRules(rules, workflow) {
    if (!(0, workflow_planning_fields_1.isAdaptiveWorkflowStartApprovalMode)(workflow.startApprovalMode)) {
        return;
    }
    rules.push(`For proceed decisions with workflow.startApprovalMode=${workflow.startApprovalMode}, include workflowStartApproval.`, "workflowStartApproval.required must decide whether explicit /alpaca start approval is required before executing this plan.", "workflowStartApproval.reason must briefly explain that start-approval decision.");
}
