Skip to content

refactor(api)!: make topology views and boundaries owner-aware - #476

Merged
acgetchell merged 5 commits into
mainfrom
refactor/461-borrowed-topology-views
Jun 23, 2026
Merged

refactor(api)!: make topology views and boundaries owner-aware#476
acgetchell merged 5 commits into
mainfrom
refactor/461-borrowed-topology-views

Conversation

@acgetchell

Copy link
Copy Markdown
Owner
  • Replace raw TDS boundary queries with one-sided facet-incidence APIs and keep true boundary classification topology-aware.
  • Add borrowed EdgeView, RidgeQuery, RidgeView, and RidgeLinkView surfaces around detached EdgeKey and RidgeCandidate values.
  • Interpret boundary facets through GlobalTopology so periodic quotient self-identifications remain closed topology.
  • Align Euler validation, focused preludes, docs, examples, benchmarks, and Semgrep rules with the new view/candidate/incidence model.

BREAKING CHANGE: BoundaryAnalysis and TDS boundary helpers are replaced by FacetIncidenceAnalysis and one-sided facet-incidence APIs. Use Triangulation::boundary_facets or DelaunayTriangulation::boundary_facets for semantic boundary queries.
BREAKING CHANGE: FacetView construction now validates and caches live-TDS access, making accessors such as vertices, simplex, opposite_vertex, and key infallible; Triangulation::facets now returns its iterator directly.
BREAKING CHANGE: Ridge topology now uses RidgeCandidate, RidgeQuery, RidgeView, and RidgeLinkView instead of detached RidgeVertices-style APIs, and topology-aware Euler/boundary helpers require GlobalTopology where classification matters.

Closes #461

- Replace raw TDS boundary queries with one-sided facet-incidence APIs and keep true boundary classification topology-aware.
- Add borrowed EdgeView, RidgeQuery, RidgeView, and RidgeLinkView surfaces around detached EdgeKey and RidgeCandidate values.
- Interpret boundary facets through GlobalTopology so periodic quotient self-identifications remain closed topology.
- Align Euler validation, focused preludes, docs, examples, benchmarks, and Semgrep rules with the new view/candidate/incidence model.

BREAKING CHANGE: BoundaryAnalysis and TDS boundary helpers are replaced by FacetIncidenceAnalysis and one-sided facet-incidence APIs. Use Triangulation::boundary_facets or DelaunayTriangulation::boundary_facets for semantic boundary queries.
BREAKING CHANGE: FacetView construction now validates and caches live-TDS access, making accessors such as vertices, simplex, opposite_vertex, and key infallible; Triangulation::facets now returns its iterator directly.
BREAKING CHANGE: Ridge topology now uses RidgeCandidate, RidgeQuery, RidgeView, and RidgeLinkView instead of detached RidgeVertices-style APIs, and topology-aware Euler/boundary helpers require GlobalTopology where classification matters.

Closes #461
@acgetchell acgetchell self-assigned this Jun 22, 2026
@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 257c98fb-e258-4da4-bbb6-a16c6d3d3c2a

📥 Commits

Reviewing files that changed from the base of the PR and between 14ea310 and 28faae2.

📒 Files selected for processing (1)
  • src/topology/ridge.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/topology/ridge.rs

Walkthrough

Adds borrowed edge and ridge views, replaces boundary-analysis with one-sided facet incidence, threads GlobalTopology through boundary and Euler validation, and updates the public API, docs, Semgrep rules, benchmarks, and tests to match the new topology model.

Changes

Facet Incidence, Borrowed Topology Views, and Validation

Layer / File(s) Summary
Core views and incidence contracts
src/core/facet.rs, src/core/simplex.rs, src/core/collections/triangulation_maps.rs, src/core/tds/storage.rs, src/core/traits/facet_cache.rs, src/core/edge.rs, src/topology/ridge.rs, src/topology/spaces/toroidal.rs, src/core/facet_incidence.rs, src/core/traits/facet_incidence_analysis.rs
FacetView caches simplex-derived data at construction, facet iteration moves to TDS-owned iterators backed by the facet-incidence index, EdgeKey::view adds a borrowed EdgeView, and RidgeCandidate/RidgeQuery/RidgeView/RidgeLinkView plus lifted toroidal identities are introduced. FacetToSimplicesMap becomes crate-private, FacetToSimplicesIndex is promoted, and cache-provider internals are tightened.
Topology-aware validation and query flow
src/core/query.rs, src/core/util/facet_utils.rs, src/core/util/jaccard.rs, src/core/algorithms/incremental_insertion.rs, src/core/algorithms/pl_manifold_repair.rs, src/bench_fixtures.rs, src/geometry/util/measures.rs, benches/*, src/core/algorithms/flips.rs, src/topology/characteristics/euler.rs, src/topology/characteristics/validation.rs, src/core/tds/errors.rs, src/core/validation.rs, src/topology/traits/topological_space.rs, src/core/triangulation.rs
FacetIncidenceAnalysis replaces BoundaryAnalysis and exposes one-sided facet iteration, ownership-checked queries, and one-sided counts. Validation now uses validated facet-degree maps with GlobalTopology, topology errors gain boundary/classification variants, Triangulation::try_set_global_topology becomes atomic on failure, and consumer code switches from boundary facets to one-sided facets.
Delaunay, convex hull, and core consumers
src/delaunay/*, src/geometry/algorithms/convex_hull.rs
Delaunay builder/validation/query/repair paths now carry requested global topology metadata explicitly, canonicalized toroidal builds report Euclidean metadata, and convex hull construction uses topology-aware boundary queries with borrowed facet views and boxed query errors.
Public wiring, docs, Semgrep, benchmarks, and tests
src/lib.rs, docs/*, semgrep.yaml, tests/*, tests/semgrep/src/project_rules/rust_style.rs, benches/*, justfile
Public re-exports, docs, Semgrep rules, benchmarks, and tests are updated to the one-sided incidence, borrowed-view, and topology-aware validation model.

Possibly related PRs

  • acgetchell/delaunay#90: Refactors the boundary-facet API surface that this PR replaces with one-sided facet incidence.
  • acgetchell/delaunay#458: Changes facet iteration semantics and consumer code around FacetView, which this PR builds on.
  • acgetchell/delaunay#474: Touches borrowed FacetView-style hull facet access that is directly updated here.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Poem

🐇 I hopped through facets, one-sided and bright,
ridge links now shimmer in borrowed moonlight.
Euclid or torus, the topology sings,
while cached little views flap their orderly wings.
No stale boundary ghosts in my carrot patch—
just clean little hops and a snug validation latch.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'refactor(api)!: make topology views and boundaries owner-aware' clearly summarizes the primary focus: refactoring APIs to introduce owner-aware topology views and boundary handling.
Description check ✅ Passed The PR description is directly related to the changeset, detailing the key refactorings: replacing boundary queries with incidence APIs, introducing borrowed view types, and aligning implementations accordingly.
Linked Issues check ✅ Passed The PR successfully implements all major objectives from issue #461: introduces EdgeView and RidgeView abstractions, separates facet incidence from boundary semantics via GlobalTopology, refactors boundary classification to be topology-aware, updates Euler validation to require GlobalTopology, and replaces BoundaryAnalysis with FacetIncidenceAnalysis throughout.
Out of Scope Changes check ✅ Passed All changes are directly aligned with issue #461 objectives. The PR consistently implements owner-aware topology views, replaces boundary analysis with facet incidence, and updates all related APIs, documentation, tests, and benchmarks in scope.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 100.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/461-borrowed-topology-views

Comment @coderabbitai help to get the list of available commands.

@codacy-production

codacy-production Bot commented Jun 22, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 817 complexity

Metric Results
Complexity 817

View in Codacy

🟢 Coverage 92.48% diff coverage · -0.05% coverage variation

Metric Results
Coverage variation -0.05% coverage variation (-1.00%)
Diff coverage 92.48% diff coverage

View coverage diff in Codacy

Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (3b6d2d4) 70021 64115 91.57%
Head commit (28faae2) 72534 (+2513) 66383 (+2268) 91.52% (-0.05%)

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#476) 4520 4180 92.48%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@codecov

codecov Bot commented Jun 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.52920% with 208 lines in your changes missing coverage. Please review.
✅ Project coverage is 91.49%. Comparing base (3b6d2d4) to head (28faae2).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/topology/ridge.rs 93.39% 97 Missing ⚠️
src/core/facet.rs 89.22% 61 Missing ⚠️
src/core/edge.rs 97.05% 9 Missing ⚠️
src/core/validation.rs 96.64% 9 Missing ⚠️
src/core/algorithms/flips.rs 91.91% 8 Missing ⚠️
src/geometry/algorithms/convex_hull.rs 88.67% 6 Missing ⚠️
src/topology/characteristics/euler.rs 92.30% 4 Missing ⚠️
src/core/query.rs 91.89% 3 Missing ⚠️
src/delaunay/builder.rs 98.70% 3 Missing ⚠️
src/delaunay/query.rs 91.17% 3 Missing ⚠️
... and 4 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #476      +/-   ##
==========================================
- Coverage   91.54%   91.49%   -0.05%     
==========================================
  Files          77       78       +1     
  Lines       69799    72313    +2514     
==========================================
+ Hits        63895    66164    +2269     
- Misses       5904     6149     +245     
Flag Coverage Δ
unittests 91.49% <94.52%> (-0.05%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (7)
src/core/tds/errors.rs (1)

1331-1354: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add the other two new validation kinds to this “all variants” table.

The production mapping now covers BoundaryFacetInClosedTopology and PeriodicIdentificationInNonPeriodicTopology, but this test only adds RidgeNotFound, so two new error paths can regress unnoticed. As per coding guidelines, "Unit tests must cover known values, error paths, and dimension-generic correctness."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/tds/errors.rs` around lines 1331 - 1354, The test
`triangulation_validation_error_kind_from_error_preserves_all_variants` is
incomplete and only includes a test case for the `RidgeNotFound` variant, but
the production code now includes two additional variants:
`BoundaryFacetInClosedTopology` and
`PeriodicIdentificationInNonPeriodicTopology`. Add two more entries to the test
cases array, following the same pattern as the existing cases (construct each
variant with appropriate test values and specify the corresponding
TriangulationValidationErrorKind variant). This ensures all error paths are
covered by the test and regressions can be caught.

Source: Coding guidelines

src/delaunay/query.rs (2)

928-979: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove the stale outer QueryError docs from facets().

facets() now returns AllFacetsIter directly, so the # Errors section claiming QueryError::TriangulationCorrupted can be returned is no longer accurate. Keep only the per-item FacetError note.

Docs fix sketch
-    /// # Errors
-    ///
-    /// Returns [`QueryError::TriangulationCorrupted`] if the facet iterator cannot
-    /// represent facet indices for this dimension. Individual iterator items
-    /// return [`FacetError`](crate::prelude::tds::FacetError) if a facet view
-    /// cannot be constructed from the current TDS state.
+    /// Individual iterator items return [`FacetError`](crate::prelude::tds::FacetError)
+    /// if a facet view cannot be constructed from the current TDS state.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/delaunay/query.rs` around lines 928 - 979, The documentation for the
`facets()` method contains stale error documentation that is no longer accurate.
The `# Errors` section currently mentions that
`QueryError::TriangulationCorrupted` can be returned, but since the method now
returns `AllFacetsIter` directly without wrapping errors at that level, this
claim is incorrect. Remove the part of the `# Errors` section that references
`QueryError::TriangulationCorrupted`, keeping only the accurate documentation
about how individual iterator items can return `FacetError` if a facet view
cannot be constructed.

502-510: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Include TopologyInvalid in the wrapper error docs.

This wrapper forwards Triangulation::boundary_facets(), which can now map topology-aware boundary classification failures to QueryError::TopologyInvalid; the docs only mention corrupted facet-index construction and still say “facet-map”.

Docs fix sketch
-    /// Returns [`QueryError::TriangulationCorrupted`] if facet-map construction
+    /// Returns [`QueryError::TriangulationCorrupted`] if facet-index construction
     /// detects invalid simplex or facet bookkeeping. The variant preserves the
     /// lower-level [`TdsError`] for diagnostics.
+    /// Returns [`QueryError::TopologyInvalid`] if topology-aware boundary
+    /// classification rejects one-sided facets for the triangulation's
+    /// `GlobalTopology`.
     /// Individual iterator items return [`FacetError`](crate::prelude::tds::FacetError)
     /// if a boundary facet cannot be created or keyed from the simplices.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/delaunay/query.rs` around lines 502 - 510, The documentation comment for
the `boundary_facets` method is incomplete and does not reflect all possible
error conditions. The method now returns `QueryError::TopologyInvalid` in
addition to `QueryError::TriangulationCorrupted`, but the docs only mention the
latter. Update the Errors section in the doc comment to include both error
variants: add documentation for `QueryError::TopologyInvalid` to describe when
topology-aware boundary classification failures occur, while keeping the
existing documentation for `QueryError::TriangulationCorrupted`. Ensure the docs
accurately describe both error paths that can be returned from the underlying
`self.tri.boundary_facets()` call.
src/delaunay/repair.rs (1)

1160-1182: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use a non-default topology or rename this regression test.

Line 1170 sets global_topology to the default Euclidean value, so a heuristic rebuild that accidentally resets metadata to the default would still pass. To keep this as a preservation regression, use a topology-compatible non-default fixture/value; otherwise rename the test to reflect that it only covers the default topology path.

As per coding guidelines, “Unit tests must cover known values, error paths, and dimension-generic correctness.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/delaunay/repair.rs` around lines 1160 - 1182, In the test function
test_heuristic_rebuild_preserves_global_topology, the global_topology variable
is set to GlobalTopology::Euclidean which is the default value. To properly test
that the heuristic rebuild preserves the topology metadata, either change
global_topology to use a non-default GlobalTopology variant (such as Spherical
if available) before calling set_global_topology, or alternatively rename the
test to accurately describe that it only validates the default topology
scenario.

Source: Coding guidelines

src/delaunay/builder.rs (1)

1368-1384: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Validate or reject non-Euclidean metadata before returning canonicalized builds.

Line 1383 attaches self.global_topology after the canonicalized-only build has already been validated as an unre-wired Euclidean triangulation. If a caller explicitly set a closed toroidal global_topology, this can return a DelaunayTriangulation whose topology-aware validation/boundary queries reject its raw open facets. Please either reject incompatible self.global_topology in this branch or set it before a final topology/Delaunay validation pass.

As per coding guidelines, “Every mutating operation must preserve invariants checked by Tds::is_valid (Level 1–3) and DelaunayTriangulation::is_valid (Level 4), or fail explicitly rather than leave triangulation in inconsistent state.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/delaunay/builder.rs` around lines 1368 - 1384, In the
BuilderTopology::Canonicalized branch, the code calls
dt.set_global_topology(self.global_topology) after
DelaunayTriangulation::try_with_topology_guarantee_and_options has already
validated the triangulation as Euclidean, breaking the invariant that topology
and triangulation must be consistent. Either reject incompatible
self.global_topology values before the DelaunayTriangulation construction
(ensuring it matches the canonicalized toroidal setup), or pass the
global_topology configuration into the try_with_topology_guarantee_and_options
call itself so validation occurs with the correct topology context in place.
This ensures that either the configuration is rejected early or the final
triangulation undergoes validation with its intended topology already applied.

Source: Coding guidelines

src/core/query.rs (1)

379-396: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Document the new topology-invalid boundary query error.

boundary_facet_keys_from_index(...) can now fail with ManifoldError, which is mapped to QueryError::TopologyInvalid, but the # Errors section only mentions corrupted facet-index construction and still says “facet-map”. Please update the public docs so callers know closed-topology boundary rejection is an expected error path.

Docs fix sketch
-    /// Returns [`QueryError::TriangulationCorrupted`] if facet-map construction
+    /// Returns [`QueryError::TriangulationCorrupted`] if facet-index construction
     /// detects invalid simplex or facet bookkeeping. The variant preserves the
     /// underlying [`TdsError`] so callers can inspect the structural failure.
+    /// Returns [`QueryError::TopologyInvalid`] if topology-aware boundary
+    /// classification rejects one-sided facets for the triangulation's
+    /// `GlobalTopology`.
     /// Individual iterator items return [`FacetError`](crate::prelude::tds::FacetError)
     /// if a boundary facet cannot be created or keyed from the simplices.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/query.rs` around lines 379 - 396, The documentation for the
boundary_facets() method needs to be updated to document the new error path. The
# Errors section currently only mentions QueryError::TriangulationCorrupted but
the method can also return QueryError::TopologyInvalid when
boundary_facet_keys_from_index() fails with ManifoldError. Update the doc
comment to include documentation for this new error variant, explaining that it
occurs when the boundary query detects closed-topology manifolds that cannot
have boundaries, and correct the reference from "facet-map" to be more accurate
to what the code actually does.
src/core/facet.rs (1)

220-223: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use one-sided/two-sided terminology in this diagnostic.

This error still equates multiplicity 1 with “boundary” and 2 with “internal”, but the new API separates TDS incidence from topology-aware boundary classification. Update the message and the matching test assertion to avoid reintroducing the old boundary semantics.

Proposed wording update
     /// Facet has invalid multiplicity (should be 1 for boundary or 2 for internal).
     #[error(
-        "Facet with key {facet_key:016x} has invalid multiplicity {found}, expected 1 (boundary) or 2 (internal)"
+        "Facet with key {facet_key:016x} has invalid multiplicity {found}, expected 1 (one-sided) or 2 (two-sided)"
     )]

Also update the assertion in src/core/facet_incidence.rs:

-                error_string.contains("expected 1 (boundary) or 2 (internal)"),
+                error_string.contains("expected 1 (one-sided) or 2 (two-sided)"),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/facet.rs` around lines 220 - 223, The InvalidMultiplicity error
message uses outdated terminology equating multiplicity 1 with "boundary" and 2
with "internal", but the new API uses one-sided and two-sided terminology
instead. Update the error string in the #[error(...)] attribute for the
InvalidMultiplicity variant to replace "boundary" with "one-sided" and
"internal" with "two-sided". Additionally, update any corresponding test
assertion in src/core/facet_incidence.rs that matches against this error message
to use the new terminology.
🧹 Nitpick comments (2)
src/geometry/algorithms/convex_hull.rs (1)

666-679: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Decouple the hull borrow from the returned FacetView lifetime.

FacetView values are backed by tri, but the current signature uses one 'tds lifetime for both &self and tri, so collected views remain unnecessarily tied to the hull borrow after the iterator is consumed.

♻️ Proposed lifetime split
-    pub fn try_facets<'tds, K>(
-        &'tds self,
-        tri: &'tds Triangulation<K, U, V, D>,
+    pub fn try_facets<'hull, 'tds, K>(
+        &'hull self,
+        tri: &'tds Triangulation<K, U, V, D>,
     ) -> Result<
-        impl Iterator<Item = Result<FacetView<'tds, U, V, D>, FacetError>> + 'tds,
+        impl Iterator<Item = Result<FacetView<'tds, U, V, D>, FacetError>> + 'hull,
         ConvexHullConstructionError,
-    > {
+    >
+    where
+        'tds: 'hull,
+    {
         self.ensure_current_for_construction(tri)?;
         let tds = &tri.tds;
         Ok(self

Please verify with a compile test that collects facet views inside a scope where the hull is dropped while the triangulation remains alive.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/geometry/algorithms/convex_hull.rs` around lines 666 - 679, The
try_facets method uses a single lifetime 'tds for both the hull reference
(&self) and the triangulation reference (&tri), which unnecessarily couples the
FacetView lifetime to the hull's borrow. Introduce a separate lifetime parameter
for the tri parameter (for example, 'a) that is distinct from 'tds used for
&self, then update the return type's Iterator to use this new lifetime parameter
instead of 'tds. This allows FacetView values to remain valid as long as the
triangulation is alive, independent of the hull's borrow lifetime. After making
this change, verify it compiles and test that facet views can be collected in a
scope where the hull reference is dropped while the triangulation reference
remains in scope.
src/core/facet.rs (1)

1419-1425: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Add #[must_use] to the public iterator wrappers.

SimplexFacetsIter, BoundaryFacetsIter, and OneSidedFacetsIter are public wrapper types; ignored iterator values should be caught consistently with the rest of the borrowed-view API.

As per coding guidelines, “public wrapper types must be #[must_use].”

Proposed attributes
 #[derive(Clone)]
+#[must_use]
 pub struct SimplexFacetsIter<'tds, U, V, const D: usize> {
     tds: &'tds Tds<U, V, D>,
     simplex_key: SimplexKey,
     next_facet_index: u16,
     facet_count: u16,
 }
+#[must_use]
 pub struct BoundaryFacetsIter<'tds, U, V, const D: usize> {
     all_facets: AllFacetsIter<'tds, U, V, D>,
     facet_to_simplices_index: FacetToSimplicesIndex<'tds, U, V, D>,
     boundary_facet_keys: FastHashSet<u64>,
 }
 #[derive(Clone)]
+#[must_use]
 pub struct OneSidedFacetsIter<'tds, U, V, const D: usize> {
     all_facets: AllFacetsIter<'tds, U, V, D>,
     facet_to_simplices_index: FacetToSimplicesIndex<'tds, U, V, D>,
 }

Also applies to: 1825-1829, 1915-1919

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/facet.rs` around lines 1419 - 1425, Add the `#[must_use]` attribute
to the three public iterator wrapper structs SimplexFacetsIter,
BoundaryFacetsIter, and OneSidedFacetsIter by placing it directly above each
struct definition. This ensures that creating these iterators without using them
will trigger compiler warnings, maintaining consistency with the rest of the
borrowed-view API.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@semgrep.yaml`:
- Line 835: The pattern-regex in the struct detection rule contains an incorrect
negative lookahead assertion `(?!'')` that fails to properly exclude Rust
lifetime parameters (which use a single quote like 'tds). Change the negative
lookahead from `(?!'')` to `(?!')` in the pattern-regex on line 835 to correctly
reject lifetime-bound view types. Additionally, update
docs/dev/tooling-alignment.md to document this semgrep rule change with a
comparison of the old versus new regex pattern and the rationale for fixing the
lifetime parameter detection.

In `@src/core/algorithms/flips.rs`:
- Around line 15912-15988: The three test functions
build_k2_inverse_context_rejects_missing_endpoint_incidence_as_adjacency,
build_k2_inverse_context_rejects_missing_edge_incidence_as_adjacency, and
build_k2_inverse_context_rejects_vertex_incidence_mismatch_as_adjacency only
test dimension D=3 by hardcoding Tds<(), (), 3>, but
build_k2_flip_context_from_edge is const-generic and supports D≥3. Create a
macro that parameterizes these three test functions by dimension and generates
the same test cases for D=3, D=4, and D=5 to comply with the coding guidelines
requiring dimension-generic tests to cover D=2 through D=5 whenever feasible.

In `@src/core/edge.rs`:
- Around line 527-554: The validation loop only iterates through v0_star to
build incident_simplices, which means if a simplex exists in v1_star but is
missing from v0_star, that inconsistency is silently dropped. After the existing
loop that processes v0_star completes, add a second validation loop that
iterates through v1_star and ensures every simplex in v1_star is already
included in incident_simplices. If any simplex from v1_star is not found in
incident_simplices, return an appropriate error (similar to
EdgeKeyError::MissingVertexIncidence) to ensure the edge incidence is validated
bidirectionally and no missing entries are silently dropped.

In `@src/core/validation.rs`:
- Around line 446-454: The TopologyError::EulerMismatch match arm is incorrectly
mapping to InvariantError::Tds(TdsError::InconsistentDataStructure) when it
should route to InvariantError::Triangulation instead to maintain consistent
error provenance. Locate the TopologyError::EulerMismatch arm in the match
statement and change the error mapping from
InvariantError::Tds(TdsError::InconsistentDataStructure) to
InvariantError::Triangulation, ensuring the format and message remain
descriptive so callers see the same provenance as the explicit
EulerCharacteristicMismatch path elsewhere in the code.

In `@src/topology/ridge.rs`:
- Around line 1-9: The module documentation for the ridge module is missing two
required elements. First, add a reference citation pointing to the relevant
entry in REFERENCES.md for the ridge-star/link validation algorithm being
implemented. Second, add a note clarifying that the ridge-link implementation is
combinatorial in nature and does not introduce any new f64 floating-point
conditioning behavior. These additions should be incorporated into the existing
module-level documentation comment that begins with the module description about
ridges being codimension-2 simplices.
- Around line 909-920: The code uses `.position(...)` in multiple locations
(around lines 1087, 1090, 1456, and 1463) to find lifted vertex occurrences,
which only returns the first match. This breaks the contract that one
RidgeCandidate may correspond to multiple lifted ridge images, potentially
dropping periodic self-identification links. Replace the `.position(...)` calls
with iterator methods that enumerate all matching lifted positions (not just the
first), and process each matching occurrence/combination accordingly. Ensure
that normalization and anchoring are performed against the actual lifted target
image for each occurrence, rather than hardcoding against only the first
quotient-key match.
- Around line 1219-1224: The function build_ridge_star_map should return an
empty ridge map when the dimension D is less than 2, as RidgeCandidate rejects D
< 2 cases and enumerating empty ridges for 1D simplices can feed impossible
codimension-2 entries into validation. Add an early return check for D < 2 in
the build_ridge_star_map function that returns Ok(FastHashMap::default())
immediately, similar to the existing check for empty simplex_count.

In `@src/topology/spaces/toroidal.rs`:
- Around line 82-86: The struct LiftedVertexId is missing the #[must_use]
attribute. Add #[must_use] as an attribute above the existing #[derive(Clone,
Debug, Eq, PartialEq)] attribute on the LiftedVertexId struct definition to
ensure that values of this public wrapper type cannot be accidentally ignored by
callers, consistent with the project's coding guidelines and similar to how
LiftedLinkEdge is already annotated.

In `@tests/proptest_convex_hull.rs`:
- Line 116: The calls to number_of_one_sided_facets() at lines 116, 215, and 236
use unwrap_or(0) which silently converts query failures into zero values that
pass through prop_assume! filters, masking real regressions. Replace
unwrap_or(0) with unwrap() on the number_of_one_sided_facets() calls to fail
fast on actual errors instead of silently skipping them, allowing the degeneracy
checks via prop_assume! to only filter based on legitimate zero/empty results
rather than hidden failures.

---

Outside diff comments:
In `@src/core/facet.rs`:
- Around line 220-223: The InvalidMultiplicity error message uses outdated
terminology equating multiplicity 1 with "boundary" and 2 with "internal", but
the new API uses one-sided and two-sided terminology instead. Update the error
string in the #[error(...)] attribute for the InvalidMultiplicity variant to
replace "boundary" with "one-sided" and "internal" with "two-sided".
Additionally, update any corresponding test assertion in
src/core/facet_incidence.rs that matches against this error message to use the
new terminology.

In `@src/core/query.rs`:
- Around line 379-396: The documentation for the boundary_facets() method needs
to be updated to document the new error path. The # Errors section currently
only mentions QueryError::TriangulationCorrupted but the method can also return
QueryError::TopologyInvalid when boundary_facet_keys_from_index() fails with
ManifoldError. Update the doc comment to include documentation for this new
error variant, explaining that it occurs when the boundary query detects
closed-topology manifolds that cannot have boundaries, and correct the reference
from "facet-map" to be more accurate to what the code actually does.

In `@src/core/tds/errors.rs`:
- Around line 1331-1354: The test
`triangulation_validation_error_kind_from_error_preserves_all_variants` is
incomplete and only includes a test case for the `RidgeNotFound` variant, but
the production code now includes two additional variants:
`BoundaryFacetInClosedTopology` and
`PeriodicIdentificationInNonPeriodicTopology`. Add two more entries to the test
cases array, following the same pattern as the existing cases (construct each
variant with appropriate test values and specify the corresponding
TriangulationValidationErrorKind variant). This ensures all error paths are
covered by the test and regressions can be caught.

In `@src/delaunay/builder.rs`:
- Around line 1368-1384: In the BuilderTopology::Canonicalized branch, the code
calls dt.set_global_topology(self.global_topology) after
DelaunayTriangulation::try_with_topology_guarantee_and_options has already
validated the triangulation as Euclidean, breaking the invariant that topology
and triangulation must be consistent. Either reject incompatible
self.global_topology values before the DelaunayTriangulation construction
(ensuring it matches the canonicalized toroidal setup), or pass the
global_topology configuration into the try_with_topology_guarantee_and_options
call itself so validation occurs with the correct topology context in place.
This ensures that either the configuration is rejected early or the final
triangulation undergoes validation with its intended topology already applied.

In `@src/delaunay/query.rs`:
- Around line 928-979: The documentation for the `facets()` method contains
stale error documentation that is no longer accurate. The `# Errors` section
currently mentions that `QueryError::TriangulationCorrupted` can be returned,
but since the method now returns `AllFacetsIter` directly without wrapping
errors at that level, this claim is incorrect. Remove the part of the `# Errors`
section that references `QueryError::TriangulationCorrupted`, keeping only the
accurate documentation about how individual iterator items can return
`FacetError` if a facet view cannot be constructed.
- Around line 502-510: The documentation comment for the `boundary_facets`
method is incomplete and does not reflect all possible error conditions. The
method now returns `QueryError::TopologyInvalid` in addition to
`QueryError::TriangulationCorrupted`, but the docs only mention the latter.
Update the Errors section in the doc comment to include both error variants: add
documentation for `QueryError::TopologyInvalid` to describe when topology-aware
boundary classification failures occur, while keeping the existing documentation
for `QueryError::TriangulationCorrupted`. Ensure the docs accurately describe
both error paths that can be returned from the underlying
`self.tri.boundary_facets()` call.

In `@src/delaunay/repair.rs`:
- Around line 1160-1182: In the test function
test_heuristic_rebuild_preserves_global_topology, the global_topology variable
is set to GlobalTopology::Euclidean which is the default value. To properly test
that the heuristic rebuild preserves the topology metadata, either change
global_topology to use a non-default GlobalTopology variant (such as Spherical
if available) before calling set_global_topology, or alternatively rename the
test to accurately describe that it only validates the default topology
scenario.

---

Nitpick comments:
In `@src/core/facet.rs`:
- Around line 1419-1425: Add the `#[must_use]` attribute to the three public
iterator wrapper structs SimplexFacetsIter, BoundaryFacetsIter, and
OneSidedFacetsIter by placing it directly above each struct definition. This
ensures that creating these iterators without using them will trigger compiler
warnings, maintaining consistency with the rest of the borrowed-view API.

In `@src/geometry/algorithms/convex_hull.rs`:
- Around line 666-679: The try_facets method uses a single lifetime 'tds for
both the hull reference (&self) and the triangulation reference (&tri), which
unnecessarily couples the FacetView lifetime to the hull's borrow. Introduce a
separate lifetime parameter for the tri parameter (for example, 'a) that is
distinct from 'tds used for &self, then update the return type's Iterator to use
this new lifetime parameter instead of 'tds. This allows FacetView values to
remain valid as long as the triangulation is alive, independent of the hull's
borrow lifetime. After making this change, verify it compiles and test that
facet views can be collected in a scope where the hull reference is dropped
while the triangulation reference remains in scope.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 64341cc9-c67b-4c26-839b-f81a6114d4fe

📥 Commits

Reviewing files that changed from the base of the PR and between 3b6d2d4 and 477e4c9.

📒 Files selected for processing (53)
  • benches/boundary_uuid_iter.rs
  • benches/common/flip_workflows.rs
  • benches/profiling_suite.rs
  • docs/api_design.md
  • docs/code_organization.md
  • docs/dev/rust.md
  • docs/dev/tooling-alignment.md
  • docs/invariants.md
  • docs/topology.md
  • docs/validation.md
  • docs/workflows.md
  • examples/triangulation_and_hull.rs
  • semgrep.yaml
  • src/bench_fixtures.rs
  • src/core/algorithms/flips.rs
  • src/core/algorithms/incremental_insertion.rs
  • src/core/algorithms/pl_manifold_repair.rs
  • src/core/collections/triangulation_maps.rs
  • src/core/edge.rs
  • src/core/facet.rs
  • src/core/facet_incidence.rs
  • src/core/query.rs
  • src/core/simplex.rs
  • src/core/tds/errors.rs
  • src/core/tds/storage.rs
  • src/core/tds/validation.rs
  • src/core/traits/boundary_analysis.rs
  • src/core/traits/facet_cache.rs
  • src/core/traits/facet_incidence_analysis.rs
  • src/core/util/facet_utils.rs
  • src/core/util/jaccard.rs
  • src/core/validation.rs
  • src/delaunay/builder.rs
  • src/delaunay/query.rs
  • src/delaunay/repair.rs
  • src/geometry/algorithms/convex_hull.rs
  • src/geometry/util/measures.rs
  • src/lib.rs
  • src/topology/characteristics/euler.rs
  • src/topology/characteristics/validation.rs
  • src/topology/manifold.rs
  • src/topology/ridge.rs
  • src/topology/spaces/toroidal.rs
  • src/topology/traits/topological_space.rs
  • tests/euler_characteristic.rs
  • tests/example_workflows.rs
  • tests/prelude_exports.rs
  • tests/proptest_convex_hull.rs
  • tests/proptest_euler_characteristic.rs
  • tests/proptest_facet.rs
  • tests/semgrep/src/project_rules/rust_style.rs
  • tests/trait_bound_ergonomics.rs
  • tests/triangulation_builder.rs
💤 Files with no reviewable changes (1)
  • src/core/traits/boundary_analysis.rs

Comment thread semgrep.yaml Outdated
Comment thread src/core/algorithms/flips.rs Outdated
Comment thread src/core/edge.rs
Comment thread src/core/validation.rs Outdated
Comment thread src/topology/ridge.rs
Comment thread src/topology/ridge.rs Outdated
Comment thread src/topology/ridge.rs
Comment thread src/topology/spaces/toroidal.rs
Comment thread tests/proptest_convex_hull.rs Outdated
- Distinguish one-sided facet incidence from semantic boundary facets, with
  boundary iterators driven by topology-approved facet handles.
- Validate facet-degree maps once as `ValidatedFacetDegreeMap` and reuse that
  proof through manifold, Euler, vertex-link, and boundary checks.
- Make construction paths derive or reject `GlobalTopology` metadata so
  Euclidean, canonicalized toroidal, and periodic image-point builds cannot
  silently describe different quotient topology.
- Tighten ridge/view/prelude docs and semgrep coverage around borrowed views,
  parse-don't-validate boundaries, and topology organization.

BREAKING CHANGE: `Triangulation::set_global_topology` is replaced by `Triangulation::try_set_global_topology`; `GlobalTopologyModel::periodic_domain` returns `Option<ToroidalDomain<D>>` instead of `Option<&[f64; D]>`; `TopologyError::EulerMismatch` is removed; and builders now reject unsupported or conflicting global topology metadata instead of accepting metadata that does not match constructed connectivity.
@acgetchell
acgetchell enabled auto-merge (squash) June 23, 2026 01:29

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/topology/traits/global_topology_model.rs (1)

247-260: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Validate coordinates before early-returning from lift_for_orientation.

With the current ordering, lift_for_orientation([f64::NAN, …], None) or canonicalized mode with any offset returns Ok(coords) without enforcing the method’s non-finite-coordinate error contract.

🛡️ Proposed fix
     fn lift_for_orientation(
         &self,
         mut coords: [f64; D],
         periodic_offset: Option<[i8; D]>,
     ) -> Result<[f64; D], GlobalTopologyModelError> {
+        // Validate finiteness before returning or performing arithmetic.
+        for (axis, coord) in coords.iter().copied().enumerate() {
+            if !coord.is_finite() {
+                return Err(GlobalTopologyModelError::NonFiniteCoordinate { axis, value: coord });
+            }
+        }
+
         // Canonicalized toroidal mode intentionally accepts optional periodic offsets but
         // does not apply them. This differs from `EuclideanModel`, which treats any
         // provided periodic offset as unsupported and returns an error.
         if !self.supports_periodic_orientation_offsets() {
             return Ok(coords);
         }
         let Some(offset) = periodic_offset else {
             return Ok(coords);
         };
-
-        // Validate finiteness before performing arithmetic
-        for (axis, coord) in coords.iter().copied().enumerate() {
-            if !coord.is_finite() {
-                return Err(GlobalTopologyModelError::NonFiniteCoordinate { axis, value: coord });
-            }
-        }
         for axis in 0..D {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/topology/traits/global_topology_model.rs` around lines 247 - 260, The
`lift_for_orientation` method has early return statements that skip coordinate
validation when `periodic_offset` is `None` or when
`!self.supports_periodic_orientation_offsets()` returns true. This allows
non-finite coordinate values (like NaN or infinity) to be returned without
error, violating the method's contract. Move the coordinate validation logic to
execute before these early returns, or add validation at the beginning of the
function to ensure all coordinate values are checked for finiteness regardless
of which return path is taken.
src/delaunay/repair.rs (1)

1160-1184: 📐 Maintainability & Code Quality | 🟡 Minor

Preservation test uses default topology with limited discrimination power.

test_heuristic_rebuild_preserves_default_global_topology sets GlobalTopology::Euclidean, which is the value a freshly constructed candidate would carry by default. If a future regression dropped the global_topology argument from with_empty_kernel_and_topology_context (lines 749–753), the candidate would still default to Euclidean and this assertion would pass despite the regression.

However, strengthening this test via non-default topology is not feasible: try_set_global_topology(GlobalTopology::Spherical) fails validation on planar triangulations (rejects with BoundaryFacetInClosedTopology), and GlobalTopology::Toroidal cannot be set post-hoc on Euclidean fixtures—it requires construction via the builder. Consider instead adding an explicit assertion that the topology context argument is actually threaded through the rebuild path, or testing the rebuild with a fixture that can legitimately support a non-Euclidean topology.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/delaunay/repair.rs` around lines 1160 - 1184, The test
`test_heuristic_rebuild_preserves_default_global_topology` uses the default
`GlobalTopology::Euclidean` value, which means if the `global_topology` argument
is inadvertently dropped from the rebuild operation in the future, the test
would still pass. Add an explicit assertion or verification mechanism that
confirms the topology context is actually being threaded through the rebuild
path in the repair operation, rather than relying on the implicit default
behavior. This could involve adding a test fixture that explicitly tracks or
verifies the topology context propagation during the rebuild process.
🧹 Nitpick comments (1)
src/delaunay/builder.rs (1)

1798-1807: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a focused test for the new D > 3 periodic guard.

This new typed error path should be covered directly so future refactors do not accidentally fall through into image construction or a different precondition error.

🧪 Suggested test coverage
+    #[test]
+    fn test_builder_toroidal_rejects_unsupported_dimension_4d() {
+        let vertices: Vec<Vertex<(), 4>> = Vec::new();
+        let result = DelaunayTriangulationBuilder::new(&vertices)
+            .try_toroidal([1.0; 4])
+            .unwrap()
+            .build::<()>();
+
+        assert_matches!(
+            result,
+            Err(DelaunayTriangulationConstructionError::Triangulation(
+                DelaunayConstructionFailure::UnsupportedPeriodicDimension {
+                    dimension: 4,
+                    max_validated_dimension: 3,
+                    tracking_issue: 416,
+                }
+            ))
+        );
+    }

As per coding guidelines, “Unit tests must cover known values, error paths, and dimension-generic correctness.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/delaunay/builder.rs` around lines 1798 - 1807, Add a focused unit test in
the builder test module that validates the new periodic dimension guard in the
delaunay builder. The test should attempt to construct a periodic Delaunay
triangulation with a dimension D greater than 3 and verify that it properly
returns the TriangulationConstructionError::UnsupportedPeriodicDimension error
with the correct dimension and tracking_issue values. This test ensures the
error path is explicitly covered and prevents future refactors from accidentally
bypassing this precondition check.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/delaunay/repair.rs`:
- Around line 1160-1184: The test
`test_heuristic_rebuild_preserves_default_global_topology` uses the default
`GlobalTopology::Euclidean` value, which means if the `global_topology` argument
is inadvertently dropped from the rebuild operation in the future, the test
would still pass. Add an explicit assertion or verification mechanism that
confirms the topology context is actually being threaded through the rebuild
path in the repair operation, rather than relying on the implicit default
behavior. This could involve adding a test fixture that explicitly tracks or
verifies the topology context propagation during the rebuild process.

In `@src/topology/traits/global_topology_model.rs`:
- Around line 247-260: The `lift_for_orientation` method has early return
statements that skip coordinate validation when `periodic_offset` is `None` or
when `!self.supports_periodic_orientation_offsets()` returns true. This allows
non-finite coordinate values (like NaN or infinity) to be returned without
error, violating the method's contract. Move the coordinate validation logic to
execute before these early returns, or add validation at the beginning of the
function to ensure all coordinate values are checked for finiteness regardless
of which return path is taken.

---

Nitpick comments:
In `@src/delaunay/builder.rs`:
- Around line 1798-1807: Add a focused unit test in the builder test module that
validates the new periodic dimension guard in the delaunay builder. The test
should attempt to construct a periodic Delaunay triangulation with a dimension D
greater than 3 and verify that it properly returns the
TriangulationConstructionError::UnsupportedPeriodicDimension error with the
correct dimension and tracking_issue values. This test ensures the error path is
explicitly covered and prevents future refactors from accidentally bypassing
this precondition check.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: e71bce44-a46e-40c3-9246-0306cca7399f

📥 Commits

Reviewing files that changed from the base of the PR and between 477e4c9 and 7b79d70.

📒 Files selected for processing (40)
  • benches/profiling_suite.rs
  • docs/dev/tooling-alignment.md
  • docs/topology.md
  • semgrep.yaml
  • src/bench_fixtures.rs
  • src/core/algorithms/flips.rs
  • src/core/algorithms/pl_manifold_repair.rs
  • src/core/collections/buffers.rs
  • src/core/collections/triangulation_maps.rs
  • src/core/edge.rs
  • src/core/facet.rs
  • src/core/facet_incidence.rs
  • src/core/orientation.rs
  • src/core/query.rs
  • src/core/tds/errors.rs
  • src/core/tds/validation.rs
  • src/core/traits/facet_incidence_analysis.rs
  • src/core/triangulation.rs
  • src/core/validation.rs
  • src/delaunay/builder.rs
  • src/delaunay/construction.rs
  • src/delaunay/insertion.rs
  • src/delaunay/query.rs
  • src/delaunay/repair.rs
  • src/delaunay/validation.rs
  • src/geometry/algorithms/convex_hull.rs
  • src/lib.rs
  • src/topology/characteristics/validation.rs
  • src/topology/manifold.rs
  • src/topology/ridge.rs
  • src/topology/spaces/toroidal.rs
  • src/topology/traits/global_topology_model.rs
  • src/topology/traits/topological_space.rs
  • tests/prelude_exports.rs
  • tests/proptest_convex_hull.rs
  • tests/proptest_facet.rs
  • tests/proptest_triangulation.rs
  • tests/semgrep/src/project_rules/rust_style.rs
  • tests/trait_bound_ergonomics.rs
  • tests/triangulation_builder.rs
✅ Files skipped from review due to trivial changes (6)
  • src/core/collections/buffers.rs
  • tests/proptest_triangulation.rs
  • src/core/traits/facet_incidence_analysis.rs
  • docs/dev/tooling-alignment.md
  • src/core/collections/triangulation_maps.rs
  • docs/topology.md
🚧 Files skipped from review as they are similar to previous changes (20)
  • benches/profiling_suite.rs
  • tests/proptest_convex_hull.rs
  • src/core/algorithms/pl_manifold_repair.rs
  • src/bench_fixtures.rs
  • tests/triangulation_builder.rs
  • src/core/tds/errors.rs
  • semgrep.yaml
  • src/core/algorithms/flips.rs
  • src/core/edge.rs
  • src/core/tds/validation.rs
  • src/core/query.rs
  • tests/trait_bound_ergonomics.rs
  • tests/prelude_exports.rs
  • src/topology/spaces/toroidal.rs
  • tests/semgrep/src/project_rules/rust_style.rs
  • src/topology/ridge.rs
  • src/core/facet_incidence.rs
  • src/lib.rs
  • src/geometry/algorithms/convex_hull.rs
  • src/core/facet.rs

- Reject non-finite toroidal orientation-lift coordinates before offset and mode short-circuits.
- Keep heuristic rebuilds covered for non-default topology context and periodic construction covered for unsupported dimensions.
- Recalibrate large-scale smoke point counts for the current performance envelope.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@justfile`:
- Around line 578-581: The justfile was modified to add or change the run_case
calls for debug_large_scale_2d, debug_large_scale_3d, debug_large_scale_4d, and
debug_large_scale_5d (lines 578-581), but the corresponding update to
docs/dev/tooling-alignment.md is missing. Add a comparison and rationale section
in docs/dev/tooling-alignment.md explaining the purpose of these debug large
scale test cases and the justification for the specific parameters used (point
counts like 32000, 9000, 1000, 160 and chunk sizes like 2000, 500, 100, 20) to
ensure alignment with project tooling documentation standards.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: b0a5a483-fba7-43f7-97eb-b4b5bad2a979

📥 Commits

Reviewing files that changed from the base of the PR and between 7b79d70 and 758a252.

📒 Files selected for processing (4)
  • justfile
  • src/delaunay/builder.rs
  • src/delaunay/repair.rs
  • src/topology/traits/global_topology_model.rs
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/delaunay/repair.rs
  • src/topology/traits/global_topology_model.rs
  • src/delaunay/builder.rs

Comment thread justfile
- Explain why `perf-large-scale-smoke` is a Delaunay-specific local guard over
  release-mode debug large-scale cases.
- Record the per-dimension point counts, progress chunks, and roughly
  50-second calibration target under the 60-second cap.
- Enumerate all lifted ridge images for periodic ridge links instead of collapsing to the first quotient-key match.
- Normalize simplex images against the actual lifted target anchor so toroidal link components keep their covering-space identity.
- Move derived ridge-star buffers into link views without extra cloning.
@acgetchell
acgetchell merged commit db3fcb3 into main Jun 23, 2026
22 checks passed
@acgetchell
acgetchell deleted the refactor/461-borrowed-topology-views branch June 23, 2026 06:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor(api): add borrowed edge and ridge topology views

1 participant