feat(cam-clear): coupled-walk collision primitives and classification #138

Merged
patman merged 3 commits from patman/island-collision into patman/island-families 2026-08-24 02:25:48 +00:00 AGit
Owner

Island lane I-e1. CoupledFront, combined_stock, collision_is_uniform, clamp_stepover_to_collision, island_fronts_collided (winding-number enclosure probe — the engulfment test proves it catches what min_loop_gap alone misses). Six focused unit tests verify these primitives standalone. Opus review PASS.

Island lane I-e1. CoupledFront, combined_stock, collision_is_uniform, clamp_stepover_to_collision, island_fronts_collided (winding-number enclosure probe — the engulfment test proves it catches what min_loop_gap alone misses). Six focused unit tests verify these primitives standalone. Opus review PASS.
feat(cam-clear): coupled-walk collision primitives and classification
Some checks failed
CI / build-test (pull_request) Failing after 4s
69780e5508
First half of the island-aware orchestration layer
(docs/superpowers/island-clearing-design.md, step I-e / ID-6). This commit
adds the collision-detection and classification machinery the coupled
outer/island walk needs; the walk itself, the cut ordering, and the
end-to-end fixtures are the follow-up commit. Split out because the two
concerns review very differently: everything here is small, local, and
independently arguable geometry, while the orchestration is one long
control-flow function.

What it adds:

- `CoupledFront`, the per-island walk cursor: an `IslandFront` (I-d) plus
  `frozen_loop_idx` (the loop index this front stopped at once a collision
  froze it) and `bound_family_idx` (which outer family member its own pass
  chain is emitted ahead of, design ID-10). `loop_at(k)` gives the front's
  loop at round `k`, clamped to the last loop actually built and pinned to
  the frozen loop once frozen; `freeze` is first-collision-wins.
- Collision detection that is not just curve-vs-curve. `min_loop_gap` (I-a)
  alone sees the two loops only as curves: it catches a genuine crossing,
  but for a pair that never crosses — the common case for concentric or
  near-concentric loops, where a shrinking outer ring can step straight past
  a growing island loop in one bisected stepover and land fully nested
  inside it — it only ever reports a positive gap, never `None`.
  `any_sample_enclosed` adds a winding-number enclosure probe to close that
  hole, treating `QueryError::OnBoundary` as enclosed since a sample landing
  exactly on the loop is the tightest possible touch. `fronts_collided`
  (outer ring vs island loop) checks enclosure one-directionally — every
  island sits inside the outer wall by construction, so that direction is
  the expected relationship, not a collision signal — while
  `island_fronts_collided` checks both directions, since neither island loop
  is expected to sit inside the other.
- `collision_is_uniform`, the design's ID-6 case-2-vs-case-3 classifier,
  deliberately local to the two colliding fronts rather than global to the
  pocket. It samples each loop's own circumference and measures the distance
  to the other loop alone, reading the design's "probe whether both fronts
  stay disjoint elsewhere" as elsewhere along their own length. Everywhere-
  close means a clean, simultaneous channel closing that terminates both
  loops without splitting either (case 2, terminal but not a refusal);
  still-far-in-places means a localized touch that would require splitting a
  loop into a piece hugging the other and a piece continuing on the open
  remainder — the boolean arrangement v1 does not have (case 3). Checked in
  both directions so either loop's shape can reveal the localized touch.
- `combined_stock` / `combined_stock_core_reached`, the outer ring plus
  every front's current loop as one `StockState`, tested against the same
  `2*max(floor, tool_radius) + tol` core bound `plan_rings` already uses for
  its own `ArcCollapsed` disambiguation. A failed inscribed-circle query on
  a degenerate remainder counts as core-reached, matching that precedent.
- `clamp_stepover_to_collision`, the gouge-safety bisection. `solve_ring`'s
  stepover search is island-ignorant, so the ring it returns may have
  overshot past an island front; this re-bisects the stepover on a pure
  collision-avoidance criterion — a different question from the engagement
  target — so the emitted ring stops at the collision. A returned stepover
  at or below tolerance means even the smallest probe collides, i.e. the
  previous ring already sits on the collision boundary.
- `ClearError::CollisionQueryFailed(QueryError)`, wrapping a coplanarity
  failure from `min_loop_gap` or `winding_number`; in practice only
  reachable when a caller supplies boundaries on different Z planes, which
  `NestedRegion` does not itself enforce.

Invariants: a reported collision is conservative in the safe direction —
enclosure and crossing both count, so the walk stops early rather than
late; `loop_at` is stable for a frozen front regardless of round index, so
a front that stopped growing still blocks the outer walk from shrinking
through it; `clamp_stepover_to_collision`'s lower bracket is always
collision-free by construction (`candidate_ring(prev, 0, r) == prev`, and
`prev` was collision-checked the previous round).

These helpers have no in-tree caller until the follow-up commit, so they
are verified here by focused unit tests rather than only by compiling:

- `coupled_front_loop_at_tracks_clamps_and_pins` — round tracking, clamping
  past the last built loop, pinning once frozen, first-collision-wins.
- `combined_stock_gathers_fronts_and_reads_core` — boundary gathering and
  the core-reached threshold in both directions.
- `collision_is_uniform_separates_channel_close_from_local_touch` — the
  ID-6 case-2 vs case-3 split on a concentric close and a localized touch.
- `fronts_collided_catches_engulfment_min_loop_gap_misses` — asserts
  `min_loop_gap` alone returns `Some` for the engulfment case, so the
  winding-number probe is demonstrably load-bearing, and that an island
  nested inside the outer ring is *not* flagged.
- `island_fronts_collided_is_bidirectional` — the island/island asymmetry
  against the outer/island case above.
- `clamp_stepover_to_collision_stops_at_the_boundary` — asserts the
  unclamped stepover really does collide, then that the clamped one lands
  below the geometric limit and is collision-free.

`circle_at` moves here from the follow-up commit, since these tests are now
its first consumer.

Co-authored-by: patman-assist <patrick-ai@kgroo.co>
chore: normalize comments
Some checks failed
CI / build-test (pull_request) Failing after 5s
ef533cb921
Co-authored-by: patman-assist <patrick-ai@kgroo.co>
style: rustfmt --edition 2024 drift fix
All checks were successful
CI / build-test (pull_request) Successful in 8m47s
9a042da339
Reformats files that predate the runner's current rustfmt; no code changes.

Co-authored-by: patman-assist <patrick-ai@kgroo.co>
patman merged commit 69f97ebe6a into patman/island-families 2026-08-24 02:25:48 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
patman/KGROO!138
No description provided.