The package root is the stable API surface. Deep imports under `inire.router.*` and `inire.geometry.*` remain accessible for advanced use, but they are unstable semi-private interfaces and may change without notice.
`RoutingResult.locked_geometry` stores canonical physical geometry only. The next run applies its own clearance rules when treating it as a static obstacle.
### Initial paths with `PathSeed`
Use `RoutingProblem.initial_paths` to provide semantic per-net seeds. Seeds are materialized with the current width, clearance, and bend collision settings for the run, and partial seeds are retried by normal routing in later iterations.
| `bend_collision_type` | `"arc"` | Bend collision/proxy model: `"arc"`, `"bbox"`, `"clipped_bbox"`, or, for backward compatibility, a custom polygon. A legacy custom polygon here is treated as both the physical bend and its proxy unless overridden by the split fields below. |
| `bend_proxy_geometry` | `None` | Optional explicit bend proxy geometry. Use this when you want a custom search/collision envelope that differs from the routed bend shape. Supplying only a custom polygon proxy warns and keeps the physical bend as the standard arc. |
| `bend_physical_geometry` | `None` | Optional explicit bend physical geometry. Use `"arc"` or a custom polygon. If you set a custom physical polygon and do not set a proxy, the proxy defaults to the same polygon. |
| `capture_frontier_trace` | `False` | Run an analysis-only reroute for reached-but-colliding nets and capture prune causes near their final conflict hotspots. |
`RoutingRunResult.conflict_trace` is an immutable tuple of post-reverify conflict snapshots. It is empty unless `RoutingOptions.diagnostics.capture_conflict_trace=True`.
Trace types:
-`ConflictTraceEntry`
-`stage`: `"iteration"`, `"restored_best"`, or `"final"`
-`iteration`: Iteration index for `"iteration"` entries, otherwise `None`
-`completed_net_ids`: Nets with collision-free reached-target paths at that stage
-`conflict_edges`: Undirected dynamic-conflict net pairs seen after full reverify
-`nets`: Per-net trace payloads in routing-order order
-`NetConflictTrace`
-`net_id`
-`outcome`
-`reached_target`
-`report`
-`conflicting_net_ids`: Dynamic conflicting nets for that stage
-`component_conflicts`: Dynamic component-pair overlaps for that stage
-`ComponentConflictTrace`
-`other_net_id`
-`self_component_index`
-`other_component_index`
The conflict trace only records dynamic net-vs-net component overlaps. Static-obstacle and self-collision details remain count-only in `RoutingReport`.
Use `scripts/record_conflict_trace.py` to capture JSON and Markdown trace artifacts for the built-in trace scenarios. The default target is `example_07_large_scale_routing_no_warm_start`.
## 8. Frontier Trace
`RoutingRunResult.frontier_trace` is an immutable tuple of per-net post-run frontier analyses. It is empty unless `RoutingOptions.diagnostics.capture_frontier_trace=True`.
Trace types:
-`NetFrontierTrace`
-`net_id`
-`hotspot_bounds`: Buffered bounds around the net's final dynamic component-overlap hotspots
-`pruned_closed_set`
-`pruned_hard_collision`
-`pruned_self_collision`
-`pruned_cost`
-`samples`: First traced prune events near those hotspots
-`FrontierPruneSample`
-`reason`: `"closed_set"`, `"hard_collision"`, `"self_collision"`, or `"cost"`
-`move_type`
-`hotspot_index`
-`parent_state`
-`end_state`
The frontier trace is observational only. It reruns only the final reached-but-colliding nets in analysis mode, with scratch metrics, after the routed result is already fixed.
Use `scripts/record_frontier_trace.py` to capture JSON and Markdown frontier-prune artifacts for the built-in trace scenarios. The default target is `example_07_large_scale_routing_no_warm_start`.
Separately from the observational trace tooling, the router may run a bounded post-loop pair-local scratch reroute before refinement when the restored best snapshot ends with final two-net reached-target dynamic conflicts. That repair phase is part of normal routing behavior and is reported through the `pair_local_search_*` counters below.
`RoutingRunResult.iteration_trace` is an immutable tuple of negotiated-congestion iteration summaries. It is empty unless `RoutingOptions.diagnostics.capture_iteration_trace=True`.
Trace types:
-`IterationTraceEntry`
-`iteration`
-`congestion_penalty`: Penalty in effect for that iteration
-`routed_net_ids`: Nets rerouted during that iteration, in routing order
-`completed_nets`
-`conflict_edges`
-`total_dynamic_collisions`
-`nodes_expanded`
-`congestion_check_calls`
-`congestion_candidate_ids`
-`congestion_exact_pair_checks`
-`net_attempts`: Per-net attribution for that iteration
-`IterationNetAttemptTrace`
-`net_id`
-`reached_target`
-`nodes_expanded`
-`congestion_check_calls`
-`pruned_closed_set`
-`pruned_cost`
-`pruned_hard_collision`
-`guidance_seed_present`
Use `scripts/record_iteration_trace.py` to capture JSON and Markdown iteration-attribution artifacts. Its default comparison target is the solved seed-42 no-warm canary versus the pathological seed-43 no-warm canary.
-`congestion_presence_cache_hits` / `congestion_presence_cache_misses`: Reuse of cached per-span booleans indicating whether a move polygon could overlap any other routed net at all.
-`congestion_presence_skips`: Number of moves that bypassed full congestion evaluation because the presence precheck found no other routed nets in any covered dynamic-grid span.
-`congestion_candidate_precheck_hits` / `congestion_candidate_precheck_misses`: Reuse of cached conservative per-span booleans indicating whether any candidate nets survive the net-envelope and grid-net broad phases.
-`congestion_candidate_precheck_skips`: Number of moves that bypassed full congestion evaluation because the candidate-net precheck found no surviving candidate nets after those broad phases.
-`congestion_candidate_nets`: Total candidate net ids returned by the dynamic net-envelope broad phase during routing.
-`congestion_net_envelope_cache_hits` / `congestion_net_envelope_cache_misses`: Reuse of cached dynamic net-envelope candidate sets keyed by the queried grid-cell span.
-`congestion_grid_net_cache_hits` / `congestion_grid_net_cache_misses`: Reuse of cached per-span candidate net ids gathered from dynamic grid occupancy.
-`congestion_grid_span_cache_hits` / `congestion_grid_span_cache_misses`: Reuse of cached dynamic-path candidate unions keyed by the queried grid-cell span.
-`congestion_lazy_resolutions`: Number of popped nodes whose pending congestion was resolved lazily.
-`congestion_lazy_requeues`: Number of lazily resolved nodes requeued after a positive congestion penalty was applied.
-`congestion_candidate_ids`: Total dynamic-path object ids returned by the congestion broad phase before exact confirmation.
Lower-level search and collision modules are semi-private implementation details. They remain accessible through deep imports for advanced use, but they are unstable and may change without notice. The stable supported entrypoint is `route(problem, options=...)`.
The current implementation structure is summarized in **[docs/architecture.md](docs/architecture.md)**. The committed example-corpus counter baseline is tracked in **[docs/performance.md](docs/performance.md)**.
Use `scripts/diff_performance_baseline.py` to compare a fresh local run against that baseline. Use `scripts/record_conflict_trace.py` for opt-in conflict-hotspot traces, `scripts/record_frontier_trace.py` for hotspot-adjacent prune traces, `scripts/record_iteration_trace.py` for per-iteration negotiated-congestion attribution, and `scripts/characterize_pair_local_search.py` to sweep example_07-style no-warm runs for pair-local repair behavior. The counter baseline is currently observational and is not enforced as a CI gate.
- Use `search.bend_physical_geometry` and `search.bend_proxy_geometry` together when you need a real custom bend shape plus a different conservative proxy.