S4.2 — Fallible, thread-safe validation core

Intent

User-supplied validation code can fail, and today that failure is invisible. Probe against oxmpl-py 0.7.0 (2026-10-08): a Python checker that raised was printed and treated as "invalid", so solve() still returned a path; KeyboardInterrupt was swallowed; a typo (s.valuez) produced 286k traceback lines over the full timeout and then a misleading "No solution found". OMPL's Python bindings raise immediately because C++ exceptions unwind through the planner; Rust has no such channel (and the wasm build is panic="abort"), so the error must be in the signature. Make failure a first-class error and make the validation traits thread-safe in one breaking change.

Decisions (ADR-0003; grilling Q4/Q5/Q6/Q7/Q18)

Acceptance criteria

Tasks

Risks

Source

Agreed in the senior-engineer grilling 2026-10-08 (decisions: repo docs/planning/adr/0003-motion-validation.md; glossary: CONTEXT.md). Regeneration spec: oxmpl - sprint-003. Line references are as of origin/main c558556 (2026-10-08), before E3. E3 renames things (rand Rng→RngExt, PyO3 with_gil→attach, edition 2024), so re-grep before trusting a line number.