S4.1 — PRM milestone budget
Intent
PRM builds its roadmap until a wall-clock timeout, so roadmap density depends on machine speed and on how expensive each validity call is. In the bindings every check crosses into Python/JS (~122k calls/s measured on pyo3), which caused the deterministic py SO(3) failure and the JS compound flake root-caused during S1.4. Add an additive milestone budget: with a seed, a budget and a deterministic checker, a roadmap becomes reproducible. Supersedes S2.1 (cancelled). Goes first in E4 because S4.3/S4.4 change the motion-check resolution, which would destabilise wall-clock-bound PRM tests.
Decisions (grilling 2026-10-08, Q3/Q17/Q19)
- Additive, not breaking: Rust
PRMhas private fields (no struct-literal construction), so a new public field is safe. - A milestone is a valid sample added to the roadmap; rejected samples do not count (glossary:
CONTEXT.md§ Roadmaps). - Construction stops at the budget or the timeout, whichever first. The timeout stays the safety cap. This amends S1.3's "timeout-only, no iteration API" for PRM construction only; no ADR (additive and easy to reverse).
milestone_count()getter, as OMPL'sPRM::milestoneCount().
Acceptance criteria
Tasks
Risks
- A budget too high for the timeout silently falls back to timeout behaviour; tests should assert the budget was reached, not just that a path was found.
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.