/** * Pure helpers behind `Model.explainPolicies()` (GitHub issue #6). * * The explain path never re-derives a policy predicate. It consumes the * fragments `WhereCompiler.compileForExplain` produced for enforcement, * projects one boolean per applied policy, and cross-checks the verdict * implied by those outcomes against the literal enforcement predicate. */ import { type CompiledPolicyFragments } from '../compilers/where.compiler'; import type { DetailedPolicy, DetailedResolution, PolicyClauseOutcome, PolicyExplanation } from './types'; /** Default candidate cap for one `explainPolicies` call. */ export declare const EXPLAIN_DEFAULT_LIMIT = 100; /** Hard candidate cap — explain evaluates every policy per candidate. */ export declare const EXPLAIN_MAX_LIMIT = 1000; /** Cypher variable holding the per-policy outcome list. */ export declare const EXPLAIN_OUTCOMES = "__explain_outcomes"; /** Cypher variable holding the literal enforcement verdict. */ export declare const EXPLAIN_VISIBLE = "__explain_visible"; /** * Validate `options.limit` for an explain call: default 100, reject * anything above 1,000 instead of silently clamping (a diagnostic must * not quietly drop the candidate an operator asked about). */ export declare function resolveExplainLimit(limit: number | undefined): number; /** How one reported policy's outcome is determined for every candidate. */ type ExplainSlot = { readonly entry: DetailedPolicy; readonly projected: number; } | { readonly entry: DetailedPolicy; readonly fixed: PolicyClauseOutcome; }; export interface ExplainPlan { /** Cypher boolean expressions projected as `__explain_outcomes`. */ readonly outcomeExpressions: ReadonlyArray; /** One slot per reported policy, in registration order. */ readonly slots: ReadonlyArray; readonly overriddenBy: string | null; /** No policy is registered for the type — reads are unconstrained. */ readonly unrestricted: boolean; } /** * Pair each detailed policy with its compiled fragments and decide which * outcomes need a per-row projection. `fragments` must come from compiling * `projectResolution(detailed)` — the SAME detailed object — so the * positional alignment below holds; it is verified by identity anyway. */ export declare function buildExplainPlan(detailed: DetailedResolution | null, fragments: CompiledPolicyFragments | null): ExplainPlan; /** * Turn one result row into its explanation and verify it. `rawVisible` is * the enforcement predicate's own value (`coalesce(, false)`); the * verdict recomputed from the per-policy outcomes MUST agree with it. * AND/OR are monotone in Cypher's three-valued logic, so reading NULL as * not-true at the leaves yields the same truth value as `coalesce` at the * root — any disagreement is an engine bug, never a valid explanation. */ export declare function interpretExplainRow(plan: ExplainPlan, rawOutcomes: unknown, rawVisible: unknown, typeName: string, row: number): Omit, 'node'>; export {}; //# sourceMappingURL=explain.d.ts.map