S4.6 — Binding error hierarchy

Intent

Python callers get a bare Exception with a message new_err(e.to_string()) — 25 sites across the four planners) and JS callers get thrown strings (map_err(|e| e.to_string()) — 30 sites. Give both bindings typed errors, and re-raise users' own exceptions unwrapped. Absorbs the backlog item "Robust binding errors" and resolves the TODO callouts at docs/src/python_api.md:129 and docs/src/js_api.md:179.

Decisions (ADR-0003; grilling Q16/Q18)

Acceptance criteria

Tasks

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-005. 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.