/** * Privacy-safe v3 progress projection for the Lark run card. * * This is deliberately a pure fold over immutable run identity (`run.json`), * the validated outer DAG, and journal events. The journal remains the state * truth; `materialize` supplies the replay-correct snapshot. In particular, * this DTO never reads attempts, manifests, resolved parameters, or arbitrary * files from disk. * * The card is intentionally less detailed than the dashboard projection: * - the outer DAG fixes `counts.total` (loop body instances and revisit * instances never inflate progress); * - only path-safe DAG ids and enum/token metadata are exposed; * - goals, parameters, free-form errors/reasons, and filesystem paths are not * part of the output type at all. */ import { type V3Dag } from './dag.js'; import type { Spec } from './contract.js'; import type { StoredEvent, V3ErrorClass } from './journal.js'; import type { V3RunEnvelope } from './run-envelope.js'; export type V3ProgressStatus = 'starting' | 'running' | 'cancelling' | 'cancelled' | 'waiting' | 'blocked' | 'succeeded' | 'failed'; export type V3ProgressSource = { kind: 'ad_hoc'; } | { kind: 'saved_definition'; workflowId: string; revisionId: string; humanVersion: number; } | { kind: 'manual_cli'; } | { kind: 'legacy_v3'; }; export interface V3ProgressCounts { /** Authored outer nodes only. Dynamic loop/revisit instances never count. */ total: number; done: number; running: number; waiting: number; blocked: number; failed: number; skipped: number; cancelled: number; pending: number; } export interface V3ProgressLoop { loopId: string; /** 0 before the first iteration starts; otherwise 1-based. */ iteration: number; maxIterations: number; granted: number; lastDecision?: 'exit' | 'continue' | 'exhausted'; } export interface V3ProgressIssue { /** Always an authored outer-DAG id, never an attempt/manifest path. */ nodeId?: string; errorClass?: V3ErrorClass; /** Included only when it is a bounded machine token, never free text. */ errorCode?: string; phase?: 'business' | 'hostEffect'; } export interface V3ProgressView { runId: string; /** Digest-pinned canonical spec title. The card owns display truncation. */ title?: string; status: V3ProgressStatus; source: V3ProgressSource; counts: V3ProgressCounts; /** Running outer node ids, in authored DAG order. */ currentNodeIds: string[]; /** Human-gated outer node ids, in authored DAG order. */ waitingNodeIds: string[]; /** Every authored outer loop, in DAG order; body instances stay private. */ loops: V3ProgressLoop[]; revisit: { /** Number of accepted revisit requests recorded in the journal. */ count: number; /** Authored nodes whose prior instance was refreshed, in DAG order. */ refreshedNodeIds: string[]; }; issue?: V3ProgressIssue; feishuHostFailed?: boolean; upstreamNonHostFinished?: boolean; /** Number only: external payloads and provider errors never enter the card. */ uncertainHostEffectCount?: number; /** Last usable journal timestamp, falling back to run.json.createdAt. */ updatedAt: string; } export interface V3ProgressProjectionInput { envelope: V3RunEnvelope; dag: V3Dag; /** The verified spec returned by `loadAuthorizedV3Run`, when this source has one. */ spec?: Spec; events: readonly StoredEvent[]; } /** * Build the stable, privacy-safe progress DTO consumed by the Lark card. * Callers must pass the envelope/DAG bytes already verified by * `loadAuthorizedV3Run`; this layer performs no I/O and cannot widen trust. */ export declare function projectV3Progress(input: V3ProgressProjectionInput): V3ProgressView; //# sourceMappingURL=progress-projection.d.ts.map