# Local G2 Soft-Anchor Candidate Recovery Design ## Goal Repair the Local G2 candidate family so that a real, same-direction curvature transition can produce a candidate accepted by the existing evaluator, without weakening vehicle-curvature, raw-range, peak-gradient, collision, clearance, deviation, or global-validation gates. ## Evidence and decision The current two-piece quintic Hermite family holds every internal primitive boundary at its original position and heading. For the real `SingleTurn` fixture, a bounded sweep of internal derivative scales (`0.50` through `1.60`) and shared curvatures within the original `[left, right]` curvature interval produced no candidate that both remained in the original curvature range and reduced peak `|dκ/ds|` by the required 20 percent. This is a geometric-family limitation, not a service-dispatch or evaluator-threshold failure. Three alternatives were considered: 1. Relax curvature/range/quality gates. Rejected: it would weaken the safety and quality contract. 2. Mark `SingleTurn` as `Unchanged`. Rejected: it contradicts the already approved main-route acceptance target and hides the incomplete candidate family. 3. Keep all outer window boundary states exact while treating each internal primitive boundary as a bounded, deterministic soft anchor. Chosen: it expands geometry freedom only inside the existing `0.10 m` deviation budget; every candidate still passes the unchanged evaluator before publication. ## Candidate construction For each `LocalG2SmoothingRegion`, the outer window endpoints remain exact position/tangent/curvature boundary conditions. At each internal curvature transition, candidate generation keeps the original vehicle heading and distance-weighted shared curvature, but may offset the internal anchor position along its original geometric normal: ```text P_soft = P_original + offset × N_travel N_travel = (-sin(travelHeading), cos(travelHeading)) ``` `travelHeading` continues to use vehicle heading for forward travel and vehicle heading minus π for reverse travel. The same offset profile is applied to all internal anchors in a combined region, so adjacent quintic pieces still share one position, heading, derivative scale, and curvature at each anchor and therefore remain G2. The finite profile order for every legal window is: 1. `offset = 0.00 m`, derivative multiplier `1.00` (exact-anchor baseline); 2. `offset = +0.05 m`, derivative multiplier `0.85`; 3. `offset = -0.05 m`, derivative multiplier `1.15`. The signed offsets are intentionally both present; vehicle turn sign and map orientation must not choose a preferred side. A two-node, one-piece region has no internal anchor and therefore emits only the exact-anchor baseline. The existing global `MaximumCandidatesPerRegion` cap remains authoritative; profile enumeration is deterministic and stops at that cap. No configuration value is added in this recovery step. The 0.05 m profile displacement is only a candidate-construction bound, not an acceptance relaxation. The unchanged evaluator must still prove the complete candidate's maximum deviation is at most the configured 0.10 m, as well as all curvature, collision, clearance, finite-value, direction, and quality gates. ## Publication and failure behavior The Task 8 pipeline continues to build candidates from the immutable original segment, evaluate them against the current path, process regions in work order, and publish reports in detector order. Soft-anchor candidates are ordinary candidates: they are never specially accepted. If none passes, the region is retained and the final result remains `Unchanged` or `PartialImprovement` as defined by the existing result contract. ## Test-first acceptance Before changing the builder, extend the real `SingleTurn` builder/evaluator regression to assert all of the following against actual preprocessor, detector, window planner, builder, and evaluator instances: - the exact-anchor baseline remains present and deterministic; - at least one emitted candidate is accepted by the unchanged evaluator; - the accepted candidate stays within the configured 0.10 m deviation limit, original curvature range, vehicle curvature limit, collision/clearance gates, and 20 percent peak-gradient-improvement gate; - the same request produces the same candidate sequence and selected result on two runs; - forward and reverse source/heading conventions remain unchanged. The test must be observed failing before production changes, then pass after the smallest builder-only implementation. Task 8 service integration must then restore `SingleTurn -> Complete` and continue to prove cancellation, rollback, two-region work order, report order, and legacy-method isolation. ## Scope Production change is limited to `LocalG2CandidateBuilder.cs`; the focused candidate verifier and existing Task 8 integration/service files may change for TDD and end-to-end coverage. The previously authorized evaluator boundary de-duplication remains part of this Task 8 recovery. No safety threshold, validator tolerance, window length, vehicle model, comparison-default method, or collision/clearance behavior changes.