/**
 * skillGuard — the DATA-guard domain for skill-graph route edges (9.51.0).
 *
 * This module completes the SkillWalker's third mover. The SkillMap is data
 * (`skillGraph()`/`defineSkillMap`), entry matchers are data (`match:` —
 * skillMatch.ts), tool-outcome route arms are data (`onToolStatus`) — the one
 * thing left opaque on a route edge was the general `when` predicate. A
 * `guard:` is its declarative twin: conditions over the hop's context and the
 * tool result's own fields, compiled ONCE into the predicate that routes AND
 * the serializable data that describes it, so the check-up can compare
 * guards, `toMermaid()` can caption them, `skill.graph_declared` can carry
 * them, and every evaluation leaves per-condition evidence on the record.
 *
 * One module owns everything a guard is and does (the skillMatch.ts law):
 *
 *   • what a guard IS        — {@link SkillGuard} (author form) and
 *                              {@link SkillGuardData} (serializable description);
 *   • how it RUNS            — {@link compileGuard}: ONE compilation returns the
 *                              predicate, the data, and the evidence evaluator;
 *   • what it PROVES WRONG   — {@link guardUnsatisfiable}: the contradictions
 *                              the check-up can honestly flag;
 *   • how it DRAWS           — {@link plainGuardCaption} / {@link mermaidGuardCaption}.
 *
 * ## The operator grammar deliberately MIRRORS footprintjs's WhereFilter
 *
 * `eq / ne / gt / gte / lt / lte / in / notIn`, every condition ANDed, with
 * per-condition evidence — the exact vocabulary and evidence shape of
 * footprintjs's `evaluateFilter` (footprintjs `src/lib/decide/evaluator.ts`).
 * It is a door-local TWIN, not an import: this module sits behind the
 * skill-graph door's no-footprintjs fence
 * (test/injection-engine/skill-graph-fence.test.ts), so the tiny operator
 * set is mirrored here and a future shared extraction is mechanical. Two
 * deliberate divergences, both because guards are compiled at BUILD time
 * while footprintjs filters arrive at run time: a malformed guard is REFUSED
 * by name at the keystroke (footprintjs dev-warns and fails the condition),
 * and there is no redaction hook (this layer has no redaction registry — the
 * summarized `actualSummary` is the bounded record, never the raw bytes).
 *
 * ## What a guard can read (the key rule)
 *
 * A guard is judged per tool result of the previous iteration's batch — the
 * same evidence every route edge fires on. Six HOP KEYS read the hop context
 * directly:
 *
 *   `toolName`, `result`, `status`  — the judged tool result (`status` only
 *                                     when the tool's envelope declared one);
 *   `iteration`, `userMessage`, `currentSkillId` — the iteration context.
 *
 * Any OTHER key reads the top-level field of that name from the RESULT
 * parsed as JSON — the shape structured tool results already have. A result
 * that is not a JSON object yields `undefined` for such keys, so the
 * condition fails and the evidence says so. NOTE the same caveat that rides
 * `InjectionContext.lastToolResult`: `result` is the string the MODEL read,
 * which artifact placement can replace with a claim ticket — a guard over
 * result fields judges what the model was told. Guard on `toolName` /
 * `status` when you want a condition placement cannot move.
 *
 * Engine-type-free by design (the view is structural), imports only the
 * closed status vocabulary from its own door — `skillGraphCheckup.ts` can
 * import it and keep its "pure over strings" law intact.
 */
/** A guard threshold value — plain data only, because a guard IS data: it
 *  rides `SkillEdge.guard`, `skill.graph_declared` and every recording, so it
 *  must survive `structuredClone` and read back as what was declared. */
export type GuardValue = string | number | boolean | null;
/** The guard operators — deliberately the footprintjs WhereFilter set. */
export type GuardOperator = 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'in' | 'notIn';
/**
 * The operators one guarded key may declare. All declared operators must
 * pass (AND), exactly as in footprintjs's `FilterOps`.
 *
 *   • `eq` / `ne`   — strict equality / inequality;
 *   • `gt`/`gte`/`lt`/`lte` — ordered comparison (numbers, or strings
 *     lexicographically — `iteration: { gte: 3 }`, `riskLevel: { gte: 'high' }`);
 *   • `in` / `notIn` — membership in a non-empty list (≤ 1000 entries, the
 *     footprintjs bound).
 */
export interface SkillGuardOps {
    readonly eq?: GuardValue;
    readonly ne?: GuardValue;
    readonly gt?: string | number;
    readonly gte?: string | number;
    readonly lt?: string | number;
    readonly lte?: string | number;
    readonly in?: readonly GuardValue[];
    readonly notIn?: readonly GuardValue[];
}
/**
 * The AUTHOR form of a route-edge guard (`SkillRouteOptions.guard`): keys to
 * operator sets, every condition ANDed. Keys resolve per the module-header
 * rule — six hop keys read the hop directly, any other key reads the result's
 * top-level JSON field.
 *
 * @example
 *   .route(triage, escalation, { guard: { riskLevel: { gte: 'high' } } })
 *   .route(triage, billing, {
 *     onToolReturn: 'lookup_order',
 *     guard: { status: { ne: 'denied' }, iteration: { lte: 5 } },
 *   })
 */
export type SkillGuard = {
    readonly [key: string]: SkillGuardOps;
};
/** One compiled guard condition, as serializable data. */
export interface GuardConditionData {
    readonly key: string;
    readonly op: GuardOperator;
    readonly value: GuardValue | readonly GuardValue[];
}
/**
 * The serializable description of a route-edge guard — what the check-up
 * compares, what `toMermaid()` captions, what `SkillEdge.guard` and the
 * `skill.graph_declared` payload carry. Pure data (survives
 * `structuredClone`); conditions in declaration order, all ANDed.
 */
export interface SkillGuardData {
    readonly conditions: readonly GuardConditionData[];
}
/** The hop view a compiled guard reads. Structural on purpose — the cursor
 *  resolver builds it from `InjectionContext` + one tool result, and this
 *  module never has to import either. */
export interface GuardHopView {
    readonly toolName: string;
    readonly result: string;
    readonly status?: string;
    readonly iteration: number;
    readonly userMessage: string;
    readonly currentSkillId?: string;
}
/**
 * One condition's evaluation, for the record — the footprintjs
 * `FilterCondition` shape, door-local: which condition, what it was judged
 * against (bounded summary, never the raw bytes), and whether it passed.
 */
export interface GuardConditionEvidence {
    readonly key: string;
    readonly op: GuardOperator;
    readonly value: GuardValue | readonly GuardValue[];
    /** The judged value, summarized to ≤ 80 chars — evidence, not a transcript. */
    readonly actualSummary: string;
    readonly passed: boolean;
}
/** A full guard evaluation: the verdict plus every condition's evidence. */
export interface GuardVerdict {
    readonly verdict: boolean;
    readonly conditions: readonly GuardConditionEvidence[];
}
/**
 * ONE compilation's three faces (the `compileMatch` pattern): the predicate
 * that routes, the data that describes it, and the evidence evaluator the
 * record quotes — all from the same conditions, so they can never describe
 * different guards.
 */
export interface CompiledGuard {
    /** Cheap boolean — short-circuits on the first failing condition. */
    readonly predicate: (view: GuardHopView) => boolean;
    /** The serializable description. */
    readonly data: SkillGuardData;
    /** The full evaluation, with per-condition evidence. Same conditions, same
     *  order, same answers as `predicate` — one compiled list feeds both. */
    readonly evaluate: (view: GuardHopView) => GuardVerdict;
}
/** The six hop keys a guard reads directly (every other key reads the
 *  result's top-level JSON field). Exported for docs/tests. */
export declare const GUARD_HOP_KEYS: readonly ["toolName", "result", "status", "iteration", "userMessage", "currentSkillId"];
/**
 * Compile a guard into its predicate + its serializable data + its evidence
 * evaluator — ONE compilation, so the predicate that routes, the data the
 * check-up compares, and the evidence the record quotes can never describe
 * different guards (the `compileMatch` law). Refuses every shape it cannot
 * honor, by name, at the keystroke: an empty guard (asserts nothing — the
 * footprintjs anti-vacuous-truth law, refused at build instead of matched
 * never), an unknown operator (a typo like `gle` must not become an edge that
 * silently never fires), a non-data threshold (a guard that cannot ride a
 * recording is not a guard), an empty or oversized `in`/`notIn` list, and the
 * prototype-pollution key set.
 */
export declare function compileGuard(guard: SkillGuard, where: string): CompiledGuard;
/**
 * The UNESCAPED caption — one grammar for naming a guard, shared by the
 * mermaid label and by prose quoting a guard back to its author (the
 * `plainMatchCaption` twin): `riskLevel ≥ high AND iteration ≤ 5`.
 */
export declare function plainGuardCaption(g: SkillGuardData): string;
/** Caption a guard-only edge for a mermaid `|…|` label — the plain caption
 *  under a leading "when", escaped once (the `mermaidMatchCaption` twin). */
export declare function mermaidGuardCaption(g: SkillGuardData): string;
/** The route-edge preconditions a guard is judged AFTER — what the edge
 *  already requires of the same result. Only the provably-comparable forms
 *  arrive here: an exact-string `onToolReturn` (a RegExp is not decided) and
 *  the declared `onToolStatus` set. */
export interface GuardPreconditions {
    readonly onToolReturnExact?: string;
    readonly onToolStatuses?: readonly string[];
}
/**
 * The check-up's honesty core: is this guard PROVABLY unsatisfiable — by its
 * own conditions, or against the edge's declared preconditions? Returns the
 * human why-clause, or `undefined` when nothing is provable (say nothing
 * rather than guess — the `compareMatchers` law).
 *
 * What is claimed, exactly (all same-key, all decidable from the data):
 *   • `eq` vs `ne`/`in`/`notIn`/ordered bounds on one key — a required value
 *     the same guard excludes;
 *   • crossed ordered bounds (`gt`/`gte` above `lt`/`lte`, same-type only);
 *   • `in` whose every member the same key's `notIn` excludes;
 *   • `status` values outside the CLOSED result-status vocabulary — a status
 *     a tool can never declare (`TOOL_RESULT_STATUSES` is the whole set);
 *   • the guard's `status`/`toolName` conditions vs the edge's own declared
 *     `onToolStatus` set / exact-string `onToolReturn` — two declarations on
 *     one edge, one of which must be wrong.
 * NOT claimed: anything across keys, anything involving result-JSON fields'
 * runtime values, RegExp `onToolReturn` intersection, mixed-type bounds.
 */
export declare function guardUnsatisfiable(g: SkillGuardData, pre?: GuardPreconditions): string | undefined;
//# sourceMappingURL=skillGuard.d.ts.map