/** * Dep-graph validator — orphan, circular, cross-epic gap, stale-dep detection. * * Pure tier-0 graph traversal (no LLM). Extends the existing dependency-check * infrastructure with three additional diagnostic categories that are not * covered by the base `validateDependencies` function: * * - `E_ORPHAN` — non-epic task with no parentId and status not terminal * - `E_CROSS_EPIC_GAP` — task A deps on task B, but A's epic has no dep on B's epic * - `E_STALE_DEP` — dep to cancelled task or done-but-gates-not-passed task * - `E_MISSING_REF` — re-exported alias for E_DEP_NOT_FOUND (base validator) * - `E_CIRCULAR` — re-exported alias for E_CIRCULAR_DEP (base validator) * * DRY contract: detectCircularDeps + validateDependencyRefs are imported from * dependency-check.ts and called here — NOT reimplemented. * * @task T1857 * @epic T1855 */ import type { Task } from '@cleocode/contracts'; /** Issue code union for dep-graph validation. */ export type DepGraphIssueCode = 'E_ORPHAN' | 'E_CIRCULAR' | 'E_CROSS_EPIC_GAP' | 'E_STALE_DEP' | 'E_MISSING_REF'; /** A single dep-graph issue. */ export interface DepGraphIssue { /** Machine-readable issue code. */ code: DepGraphIssueCode; /** The task ID where the issue originates. */ taskId: string; /** Human-readable description. */ message: string; /** Related task IDs (dep IDs, cycle members, etc.). */ relatedIds?: string[]; /** Source epic ID (for cross-epic gap issues). */ epicA?: string; /** Target epic ID (for cross-epic gap issues). */ epicB?: string; } /** Result of running the full dep-graph validation. */ export interface DepGraphValidateResult { /** True when no issues were found. */ valid: boolean; /** All detected issues. Empty when valid. */ issues: DepGraphIssue[]; /** Human-readable summary line. */ summary: string; } /** Scope for validation — which tasks to include. */ export type DepValidateScope = 'all' | 'open' | 'critical'; /** * Walk up the parentId chain until reaching an epic-typed task. * Returns the nearest ancestor epic ID, or null if none exists. * * @param taskId - Starting task ID. * @param taskMap - Map of all tasks keyed by ID. * @returns The ID of the nearest ancestor epic, or null. */ export declare function nearestEpic(taskId: string, taskMap: Map): string | null; /** * Detect orphaned tasks: non-epic tasks with no parentId that are not in a * terminal state (done / cancelled / archived). * * An orphan is any task where: * - `task.type !== 'epic'` * - `!task.parentId` * - `task.status not in { done, cancelled, archived }` * * @param tasks - Full task list to analyse. * @returns Array of `E_ORPHAN` issues. */ export declare function detectOrphans(tasks: Task[]): DepGraphIssue[]; /** * Detect cross-epic dependency gaps. * * A gap exists when task A (in epic X) depends on task B (in epic Y), but * epic X has no explicit dep on epic Y. Only nearest-epic-level gaps are * reported (grandparent cascading is NOT checked — Q2 approved default). * * @param tasks - Full task list. * @returns Array of `E_CROSS_EPIC_GAP` issues. */ export declare function detectCrossEpicGaps(tasks: Task[]): DepGraphIssue[]; /** * Detect stale dependencies: deps pointing to cancelled tasks, or deps pointing * to done tasks whose verification gates were not all passed. * * @param tasks - Full task list. * @returns Array of `E_STALE_DEP` issues. */ export declare function detectStaleDeps(tasks: Task[]): DepGraphIssue[]; /** * Run the full dep-graph validation over a task set. * * Runs (in order): * 1. Missing-ref detection (E_MISSING_REF) via validateDependencyRefs * 2. Circular-dep detection (E_CIRCULAR) via detectCircularDeps * 3. Orphan detection (E_ORPHAN) * 4. Cross-epic gap detection (E_CROSS_EPIC_GAP) * 5. Stale-dep detection (E_STALE_DEP) * * @param tasks - Tasks to validate (already filtered by scope if applicable). * @param allTasks - Optional full unscoped task list used to distinguish ARCHIVED * deps from truly missing ones (T1954). When omitted, falls back to `tasks`. * @returns Structured validation result with all issues. */ export declare function validateDepGraph(tasks: Task[], allTasks?: Task[]): DepGraphValidateResult; /** * Run dep-graph validation over a task set with optional epic scoping and * scope filtering. * * Passes the full unscoped `allTasks` list to {@link validateDepGraph} so that * deps pointing to archived tasks outside the current scope are correctly * treated as satisfied rather than missing (T1954). * * @param allTasks - All tasks in the project. * @param opts - Optional epic scope and task scope filter. * @returns Validation result. */ export declare function runValidation(allTasks: Task[], opts?: { epicId?: string; scope?: DepValidateScope; }): DepGraphValidateResult; //# sourceMappingURL=dep-graph-validator.d.ts.map