/**
 * M3: Mission persistence (minimal form).
 *
 * A mission is a persistent record of a multi-task goal so the plan lives in
 * the system rather than in the coordinator LLM's context. Coordinator
 * sessions can die or compact; a new coordinator reads the mission back at
 * launch and continues.
 *
 * Explicit non-goals (see docs/mesh-product-plan-v2.md Phase M3): this is not
 * a workflow engine and there is no automatic takeover daemon. Progress is
 * never stored — it is derived from queue task statuses (mission_id) at
 * query time.
 */
import { type MeshMissionStats } from './mesh-task-stats.js';
export type MeshMissionStatus = 'active' | 'paused' | 'completed' | 'abandoned';
export declare const MESH_MISSION_STATUSES: MeshMissionStatus[];
/**
 * Provenance of a mission. `magi` marks an inline mission auto-created by a
 * mesh_magi_review fan-out (one per cross-verification run). `coordinator` (the
 * default semantic for an unstamped/legacy mission) marks a coordinator- or
 * user-authored mission. Used to bound the accumulation of completed MAGI missions
 * out of the default mesh_mission_list surface — see listMeshMissionSummaries.
 */
export type MeshMissionSource = 'magi' | 'coordinator';
export interface MeshMissionRecord {
    id: string;
    meshId: string;
    title: string;
    goal: string;
    status: MeshMissionStatus;
    /**
     * Optional provenance tag. Absent on missions created before this field existed
     * and on coordinator/user missions that don't bother stamping it — both are
     * treated as coordinator missions (never auto-hidden). Only explicit `magi`
     * missions are bounded out of the default list once completed.
     */
    source?: MeshMissionSource;
    /**
     * G3: idempotency marker for the mission_close_candidate nudge. ISO timestamp of
     * the last emit; absent/undefined when the mission has not (or no longer) been in a
     * fully-terminal state. Owned by maybeEmitMissionCloseCandidate — never set by a
     * regular upsert. See summarizeMissionTasks / maybeEmitMissionCloseCandidate.
     */
    closeCandidateEmittedAt?: string;
    createdAt: string;
    updatedAt: string;
}
export interface MeshMissionTaskAggregate {
    total: number;
    pending: number;
    assigned: number;
    completed: number;
    failed: number;
    cancelled: number;
    /** Pending tasks held back by a dependency failure (blockedReason set). */
    blocked: number;
    /** Latest updatedAt across the mission's tasks, or null with no tasks. */
    lastActivityAt: string | null;
}
export interface MeshMissionSummary extends MeshMissionRecord {
    tasks: MeshMissionTaskAggregate;
    /**
     * Operational rollup (durations / attempts) derived from the ledger via
     * computeMeshMissionStats. Optional: only populated by surfaces that opt in
     * (e.g. mesh_status), since the rollup scans a bounded ledger tail per
     * mission. Absent on the lightweight task-aggregate-only summaries.
     */
    stats?: MeshMissionStats;
}
/**
 * Slim mission summary for the mesh_status compact (default) surface. Drops the
 * full `goal` text — which can be hundreds of chars per mission and is repeated
 * for every mission on every status call — keeping only a short preview plus a
 * `goalTruncated` flag when the original was longer. The stored goal is never
 * mutated; this is an output-only projection. Coordinators that need the full
 * goal call mesh_status with verbose=true, or read the mission directly via
 * mesh_mission_upsert / getMeshMission.
 */
export interface MeshMissionSlimSummary extends Omit<MeshMissionSummary, 'goal'> {
    /** Short preview of the goal (≤ GOAL_PREVIEW_MAX chars), '' when goal empty. */
    goalPreview: string;
    /** True when the stored goal was longer than the preview (full text elided). */
    goalTruncated: boolean;
}
/** Max chars of goal text retained in the slim (compact) mission summary. */
export declare const GOAL_PREVIEW_MAX = 120;
/**
 * Shorter goal preview used by the mesh_status compact (LLM coordinator) surface.
 * The coordinator only needs to recognize a mission, not read its full goal, and
 * mesh_status repeats every live mission on every poll — so the status preview is
 * tighter than the dashboard / mesh_mission_list preview (GOAL_PREVIEW_MAX).
 */
export declare const COMPACT_STATUS_GOAL_PREVIEW_MAX = 80;
/**
 * mesh_mission_list default fold sizes. Without an explicit `statuses` filter the
 * tool returns non-terminal (active/paused) missions in full detail but folds the
 * completed/abandoned history into counts + a capped newest-first id list — a mesh
 * can accumulate hundreds of terminal missions and returning them all (each with a
 * ledger-scanned stats rollup) blew past the tool payload / token budget and spilled
 * to a file. When an explicit `statuses` filter IS given, the matching missions are
 * returned in detail but still bounded by MESH_MISSION_LIST_STATUS_LIMIT so a
 * status:["completed"] call on a huge history stays bounded (overflow → truncated).
 */
export declare const MESH_MISSION_LIST_HISTORY_ID_LIMIT = 30;
export declare const MESH_MISSION_LIST_STATUS_LIMIT = 50;
export declare function upsertMeshMission(meshId: string, input: {
    id?: string;
    title: string;
    goal?: string;
    status?: string;
    source?: MeshMissionSource;
}): MeshMissionRecord;
export declare function getMeshMissions(meshId: string, statuses?: MeshMissionStatus[]): MeshMissionRecord[];
export declare function getMeshMission(meshId: string, missionId: string): MeshMissionRecord | null;
/** Aggregate task statuses for a mission at query time (no stored progress). */
export declare function summarizeMissionTasks(meshId: string, missionId: string): MeshMissionTaskAggregate;
export declare function summarizeMeshMission(meshId: string, mission: MeshMissionRecord): MeshMissionSummary;
/**
 * G3 — all-tasks-terminal detection: true when a mission has at least one task and
 * every task has reached a terminal status (no pending, no assigned). This is the
 * derived signal (never a stored flag) that a mission has no more work in flight and
 * is a candidate for the coordinator to close. A mission with zero tasks is NOT a
 * candidate — an empty mission is a freshly-created plan, not a finished one.
 */
export declare function isMissionAllTasksTerminal(aggregate: MeshMissionTaskAggregate): boolean;
/**
 * G3 (step ①) — emit a `mission_close_candidate` coordinator nudge the first time an
 * ACTIVE mission's tasks all become terminal, and reset the idempotency marker when a
 * mission leaves the terminal state. Call this after any task-status mutation that can
 * change a mission's aggregate (completion / failure / cancel / dependency-failure /
 * new task). Fire-and-forget and fully best-effort — a throw here must never break the
 * task mutation that triggered it.
 *
 * Design invariants (docs/MESH_PROMPT_ARCH_REVIEW_2026-07.md §9-1 G3):
 *  - NEVER transitions the mission status. This only publishes a "consider closing"
 *    hint; the coordinator/human decides via mesh_mission_upsert.
 *  - Idempotent per all-terminal EDGE. The mission's close_candidate_emitted_at marker
 *    guarantees exactly one emit per terminal transition; while the mission stays
 *    all-terminal, subsequent calls no-op (no per-tick spam). When the mission returns
 *    to non-terminal (a new/re-opened task), the marker is cleared so a later
 *    re-completion nudges again.
 *  - Only ACTIVE missions nudge. A paused/completed/abandoned mission is never a
 *    close candidate (already decided, or intentionally on hold).
 *
 * Returns true iff an event was emitted on this call.
 */
export declare function maybeEmitMissionCloseCandidate(meshId: string, missionId: string): boolean;
/** Active mission summaries for mesh_status / coordinator prompt injection. */
export declare function getActiveMeshMissionSummaries(meshId: string): MeshMissionSummary[];
/**
 * Mission summaries for the mesh_status dashboard surface: every active/paused
 * mission plus a capped, newest-first slice of completed/abandoned history so
 * the dashboard can render a collapsible "history" section without unbounded
 * payload growth. Returned newest-first within each group (active/paused first,
 * then history), so the frontend can split on `status` directly.
 *
 * Compact mode (the default) elides each mission's full `goal` text — which is
 * repeated verbatim on every status poll and dominates the payload when a mesh
 * has many missions — returning only a short `goalPreview` + `goalTruncated`
 * flag. Pass `verbose: true` to get the full `goal` text per mission. The stored
 * goal is untouched in both modes; this is an output-only projection.
 */
export declare function getMeshStatusMissionSummaries(meshId: string, options?: {
    historyLimit?: number;
    verbose?: boolean;
    withStats?: boolean;
}): MeshMissionSummary[] | MeshMissionSlimSummary[];
/** Folded completed/abandoned history for the mesh_status compact surface. */
export interface MeshStatusMissionsHistoryFold {
    /** Total completed + abandoned missions. */
    count: number;
    /** Count by lifecycle status (e.g. { completed, abandoned }). */
    byStatus: Record<string, number>;
    /** Newest-first id list (capped) so each folded mission stays addressable. */
    missionIds: string[];
    note: string;
}
/** Compact mesh_status mission projection: live detail + folded history. */
export interface MeshStatusMissionsCompact {
    /**
     * Active + paused missions, goal-elided to COMPACT_STATUS_GOAL_PREVIEW_MAX and
     * WITHOUT the operational `stats` rollup — the `tasks` aggregate already carries
     * progress, and stats (durations/retries) is a verbose/dashboard concern.
     */
    live: MeshMissionSlimSummary[];
    /** Completed + abandoned missions folded to counts + ids; null when none. */
    historyFold: MeshStatusMissionsHistoryFold | null;
}
/**
 * Mission projection for the mesh_status COMPACT (LLM coordinator) surface.
 *
 * Unlike getMeshStatusMissionSummaries (which emits every live mission plus a
 * capped slice of full-detail history, each carrying a stats rollup), this keeps
 * per-mission detail ONLY for live (active/paused) missions and folds the whole
 * completed/abandoned history into a counts + id-list summary. Combined with the
 * tighter goal preview and dropped stats, this is what keeps the compact
 * mesh_status payload bounded as a mesh accumulates missions — the missions
 * section previously dominated the payload (full goalPreview + tasks + stats per
 * mission, for every live mission and up to 10 history missions, on every poll).
 *
 * The stored missions are untouched; this is an output-only projection. Full
 * mission detail (goal text + stats + history) stays available via
 * mesh_status verbose=true or mesh_mission_list.
 */
export declare function getMeshStatusMissionsCompact(meshId: string, options?: {
    previewMax?: number;
    historyIdLimit?: number;
}): MeshStatusMissionsCompact;
/**
 * Read-only mission listing for the mesh_mission_list tool. Returns summaries
 * (record + live task aggregate) for missions matching `statuses` — or every
 * mission when `statuses` is omitted/empty — newest-first by updatedAt. Unlike
 * getMeshStatusMissionSummaries this does NOT cap or group by lifecycle, so a
 * coordinator can deliberately surface paused/abandoned/completed missions that
 * the live status view would hide or truncate.
 *
 * MAGI bounding: by default this EXCLUDES completed MAGI missions (source==='magi'
 * && status==='completed') — a mesh_magi_review fan-out auto-creates one inline
 * mission per run and auto-closes it on collection, so without this they accumulate
 * unbounded and drown out coordinator missions in the list. In-progress MAGI missions
 * (active/paused) are still shown so a running cross-verification stays visible. Pass
 * `includeMagi: true` to return every mission including completed MAGI ones. A mission
 * with no `source` (legacy / coordinator) is never affected.
 *
 * Compact (the default) elides each goal to a capped preview + goalTruncated
 * flag; verbose returns the full goal text. The stored goal is never mutated.
 */
export declare function listMeshMissionSummaries(meshId: string, options?: {
    statuses?: MeshMissionStatus[];
    verbose?: boolean;
    includeMagi?: boolean;
}): MeshMissionSummary[] | MeshMissionSlimSummary[];
/** Shaped mesh_mission_list result: bounded detail list + optional folded history. */
export interface MeshMissionListResult {
    /** Detailed (slim or verbose) mission summaries — bounded, newest-first. */
    missions: MeshMissionSummary[] | MeshMissionSlimSummary[];
    /**
     * Completed/abandoned missions folded to counts + ids. Present (default path)
     * when no explicit status filter is given and terminal missions exist. Null when
     * an explicit status filter is active (those missions go into `missions`).
     */
    historyFold: MeshStatusMissionsHistoryFold | null;
    /** True when an explicit status filter matched more than `limit` missions. */
    truncated: boolean;
    /** Total missions matching the query BEFORE the detail-list cap was applied. */
    matched: number;
    /** Newest-first ids of missions dropped by the detail-list cap (truncated path). */
    overflowIds?: string[];
}
/**
 * mesh_mission_list projection: payload-bounded regardless of mesh mission count.
 *
 * Default (no explicit `statuses`): non-terminal missions (active/paused) return in
 * detail; completed/abandoned missions are folded to counts + a capped id list
 * (historyFold), NOT emitted one-by-one. This is what keeps the tool from returning
 * hundreds of terminal missions (each with a ledger stats rollup) and overflowing the
 * token budget.
 *
 * Explicit `statuses` (e.g. ["completed"]): the coordinator asked to see those
 * missions, so they ARE returned in detail — but still bounded by `limit` (default
 * MESH_MISSION_LIST_STATUS_LIMIT). Overflow beyond `limit` is reported via
 * truncated:true + overflowIds rather than silently dropped.
 *
 * MAGI + verbose semantics match listMeshMissionSummaries. `withStats` opts each
 * detailed mission into the ledger-scanned stats rollup (off by default — the tasks
 * aggregate is enough for a list view).
 */
export declare function listMeshMissionsForTool(meshId: string, options?: {
    statuses?: MeshMissionStatus[];
    verbose?: boolean;
    includeMagi?: boolean;
    withStats?: boolean;
    limit?: number;
    historyIdLimit?: number;
}): MeshMissionListResult;
/**
 * M3-3: render active missions as a prompt section for {{mission}}.
 * Empty string when no active mission — the prompt stays byte-identical to
 * the pre-M3 output in that case (regression guarantee).
 */
export declare function buildMissionPromptSection(meshId: string): string;
