/** * Minimal, dependency-free JSON-Logic evaluator for the ContentPolicyGate ruleset. * * Policy rules are PURE DATA (JSON) — there is no code-execution surface — so a * legal/illegal ruleset can live in a database or a per-jurisdiction file and be * swapped WITHOUT a redeploy. That swap-without-deploy property (and the absence * of an embedded interpreter) is the reason we use a small JSON-Logic subset here * rather than pulling an OPA/Cedar runtime into the TS monorepo: the survey in * research/2026-06-13 recommends rules-as-data for jurisdiction-varying policy, * keeping a heavier engine as a later drop-in if scale demands it. * * This is intentionally NOT full JsonLogic. It supports exactly the operator * subset the policy rules need, with a recursion-depth cap and a regex-length cap * so a hostile rule file cannot hang the evaluator (ReDoS / stack blow-up). */ export type JsonLogicPrimitive = string | number | boolean | null; export type JsonLogicExpr = { [operator: string]: unknown; }; export type JsonLogicRule = JsonLogicPrimitive | JsonLogicExpr | JsonLogicRule[]; /** * Evaluate a JSON-Logic rule against a facts object. Returns the computed value * (primitives evaluate to themselves; logic nodes evaluate their operator). * Unknown operators and malformed nodes evaluate to `null` (falsy) rather than * throwing — a broken rule fails CLOSED for `block` predicates because a `null` * result is falsy, so it never silently allows. */ export declare function evaluateJsonLogic(rule: JsonLogicRule, data: Record, depth?: number): unknown; /** Convenience: evaluate a rule and coerce the result to a boolean (truthy). */ export declare function matchesRule(rule: JsonLogicRule, facts: Record): boolean; //# sourceMappingURL=jsonLogic.d.ts.map