For agents, on top of README.md, which they read first.

  • The crate's invariants are two folders up, in crates/postjevsql-pg/CLAUDE.md; the wrapper's traps (pg_guard on every callback, no Rust pointer in custom_private, EndCustomScan not called on error, rescan required) are the root CLAUDE.md's Implementation §1.
  • Never let a call reach the per-row function body. A new place a call can appear needs a hook that wraps it, or guard.rs must refuse it; a plan that evaluates a call outside a jev scan would have spent money before the body refuses.
  • The child plan is built with the jev quals removed (take_calls). A child that kept them would judge rows one at a time, outside any request, in both modes, ForeignScan included.
  • Reach may only widen, never narrow. A condition that cannot be evaluated twice with the same result (it reads a call's answer, a volatile function, a SubPlan, a CASE x WHEN placeholder) is dropped, so the call is judged as before. Keeping such a condition could skip a call Postgres does read.
  • An EvalPlanQual recheck never sends. A row version the statement did not judge is refused with 40001 (Statement::rechecking); do not give a recheck a client.