/** * v1.3.2 §9.1 — domain-agnostic validation core. * * The five managers (skill · agent · workflow · goal · cron) all emit the * same shape: an `{ ok, errors[], warnings[] }` result over findings of the * form `{ code, message, field? }`, accumulated imperatively. Before this * module each validator hand-rolled two arrays and the `ok: errors.length===0` * return. `Findings` centralizes that idiom so a manager only writes its rules; * `runRules` offers a declarative alternative for rule-set–style validators. * * Pure — no fs, no domain types. Generic over a finding type `F` so each * domain keeps its own extra fields (e.g. workflow's `stage`, cron's `id`). */ export interface BaseFinding { code: string; message: string; field?: string; } export interface ValidationResult { ok: boolean; errors: F[]; warnings: F[]; } /** * Mutable accumulator. Push findings as you discover them, then call * `.result()`. The `*If` helpers fold the ubiquitous * `if (cond) errors.push(...)` pattern into one call so a validator body reads * as a flat list of rules. */ export declare class Findings { readonly errors: F[]; readonly warnings: F[]; error(finding: F): this; warn(finding: F): this; /** Push an error only when `condition` holds. Returns `condition` so callers * can short-circuit further checks: `if (f.errorIf(!id, {...})) return f.result();` */ errorIf(condition: boolean, finding: F): boolean; warnIf(condition: boolean, finding: F): boolean; /** Fold another result's findings into this collector (e.g. a sub-validator). */ merge(other: ValidationResult): this; result(): ValidationResult; } export type Severity = "error" | "warning"; /** A rule maps a subject to zero or more severity-tagged findings. */ export type Rule = (subject: S) => Array<{ severity: Severity; finding: F; }> | { severity: Severity; finding: F; } | null | undefined; /** Declarative runner: apply every rule to `subject`, collect into one result. */ export declare function runRules(subject: S, rules: Rule[]): ValidationResult;