Skip to content

Refactor/387 tds mutation boundaries#390

Merged
acgetchell merged 5 commits into
mainfrom
refactor/387-tds-mutation-boundaries
May 17, 2026
Merged

Refactor/387 tds mutation boundaries#390
acgetchell merged 5 commits into
mainfrom
refactor/387-tds-mutation-boundaries

Conversation

@acgetchell
Copy link
Copy Markdown
Owner

Closes #387

- Update the README pitch, feature list, references, and docs.rs-facing guidance
  around exact predicates, SoS, PL-manifold validation, and bistellar repair.
- Refresh roadmap, release, limitation, robustness, orientation, invariant,
  diagnostics, property-testing, workflow, and validation docs for the v0.7.8
  cleanup path and v0.8.0 paper-facing work.
- Align contributor and script docs around non-mutating `just` checks before
  mutating fixes.
- Update generated benchmark-summary guidance to surface `just bench-perf-summary`,
  current Criterion metadata, and large-scale characterization defaults.
- Represent cell neighbor slots as typed boundary, neighbor, and unassigned states so validation can reject stale assignment buffers.
- Make `Cell::neighbors()` zero-copy and add explicit `neighbor_key()` and `neighbor_slots()` read APIs for indexed or typed access.
- Keep `Vertex::incident_cell` mutation crate-owned and migrate insertion, flip, validation, example, benchmark, and property-test call sites.
- Harden CI performance summary parsing so stale or malformed simplex-count sidecars are skipped, and make generated predicate performance notes dimension-dependent.

BREAKING CHANGE: `Cell::neighbors()` now returns an iterator over `Option<CellKey>` instead of an owned `NeighborBuffer<Option<CellKey>>`. Direct field mutation of cell neighbors and vertex incident-cell pointers is no longer public; callers should use the read APIs and TDS-owned mutation paths.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 16, 2026

Review Change Stack

Walkthrough

Replace per-cell optional neighbor buffers with typed NeighborSlot (Unassigned/Boundary/Neighbor), encapsulate Vertex incident-cell via getter/setter, and migrate TDS, triangulation, algorithm, tests, docs, and benchmarks to use neighbor_keys()/neighbor_key()/set_neighbors_from_keys(); add cached same-machine benchmark baseline and compare-ref CLI flow.

Changes

TDS neighbor and incident-cell encapsulation refactoring

Layer / File(s) Summary
Typed neighbor-slot representation and Cell API
src/core/cell.rs
Introduce NeighborSlot enum and change Cell neighbor storage to Option<NeighborBuffer<NeighborSlot>>; add neighbor_key(), neighbor_keys(), neighbor_slots()/neighbor_slots_mut(), set_neighbors_from_keys(), ensure_neighbors_buffer_mut(); add UnassignedNeighborSlot validation.
Vertex incident-cell encapsulation
src/core/vertex.rs
Make incident_cell crate-only; add public incident_cell() accessor and pub(crate) set_incident_cell() mutator used by TDS code and tests.
TDS core topology operations and neighbor assignments
src/core/tds.rs
assign_neighbors, BFS traversals, neighbor repair, removal and incident-cell repair now use key/slot APIs (neighbor_keys(), neighbor_key(...).flatten(), set_neighbors_from_keys()); add NeighborValidationError::UnassignedNeighborSlot and helper validators.
Triangulation adjacency and incident-cell management
src/core/triangulation.rs
Traversal, adjacency index, cavity reduction, hull extension, and incident-cell bookkeeping updated to use neighbor-key APIs and incident-cell accessor/setter; tests adjusted to new fixtures/helpers.
Algorithm neighbor traversal and mutation
src/core/algorithms/flips.rs, src/core/algorithms/incremental_insertion.rs, src/core/algorithms/locate.rs
Flip trial validation, k=2/k=3 traversal, cavity wiring, neighbor repair, locate/conflict-region BFS use neighbor slot/key APIs and set_neighbors_from_keys; added facet-index validation and tests for unassigned-slot rejection.
Manifold repair and Delaunay validation updates
src/core/algorithms/pl_manifold_repair.rs, src/core/util/delaunay_validation.rs
Use incident_cell() accessor for orphan detection; Delaunay violation detail now preserves NeighborSlot per-facet and debug output iterates neighbor_slots(); tests updated.
Test suite, examples, and docs
tests/*, examples/*, benches/*, README.md, docs/*, CITATION.cff, justfile
Update neighbor iteration patterns (e.g., .iter().enumerate().enumerate()), use set_neighbors_from_keys() for fixtures, add NeighborSlot to preludes, update performance docs and compare-result filenames, and add new justfile recipes for checks.
Benchmark utils and CLI
scripts/benchmark_utils.py, scripts/tests/test_benchmark_utils.py
Make CI metric sidecar parsing permissive; add _ci_suite_metric_simplices(); implement cached same-machine ref baseline, ensure-ref-baseline and compare-ref CLI subcommands; refactor comparison summary to compute per-benchmark mean-time changes in µs and geomean/median/total summaries; update tests and constants for new filenames.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

"🐰 I hopped through slots and keys so neat,
boundary, neighbor, unassigned — all discrete.
Accessors guard the hops I make,
topology stays whole for safety’s sake.
Benchmarks hum, the tests all greet."

✨ 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/387-tds-mutation-boundaries

@acgetchell acgetchell enabled auto-merge (squash) May 16, 2026 18:33
@codacy-production
Copy link
Copy Markdown

codacy-production Bot commented May 16, 2026

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 4 complexity

Metric Results
Complexity 4

View in Codacy

🟢 Coverage 93.02% diff coverage · +0.06% coverage variation

Metric Results
Coverage variation +0.06% coverage variation (-1.00%)
Diff coverage 93.02% diff coverage

View coverage diff in Codacy

Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (526583c) 60205 54425 90.40%
Head commit (2feb6a0) 60458 (+253) 54692 (+267) 90.46% (+0.06%)

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 (#390) 774 720 93.02%

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
Copy link
Copy Markdown

codecov Bot commented May 16, 2026

Codecov Report

❌ Patch coverage is 93.02326% with 54 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.45%. Comparing base (526583c) to head (2feb6a0).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/core/tds.rs 94.02% 20 Missing ⚠️
src/core/algorithms/incremental_insertion.rs 86.41% 11 Missing ⚠️
src/core/triangulation.rs 88.04% 11 Missing ⚠️
src/core/algorithms/flips.rs 93.67% 5 Missing ⚠️
src/core/util/delaunay_validation.rs 88.57% 4 Missing ⚠️
src/core/algorithms/locate.rs 85.00% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #390      +/-   ##
==========================================
+ Coverage   90.39%   90.45%   +0.06%     
==========================================
  Files          61       61              
  Lines       60007    60260     +253     
==========================================
+ Hits        54241    54508     +267     
+ Misses       5766     5752      -14     
Flag Coverage Δ
unittests 90.45% <93.02%> (+0.06%) ⬆️

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

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

@acgetchell
Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 16, 2026

✅ Actions performed

Full review triggered.

@acgetchell
Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 16, 2026

✅ Actions performed

Full review triggered.

@coderabbitai coderabbitai Bot added documentation Improvements or additions to documentation enhancement New feature or request rust Pull requests that update rust code breaking change geometry Geometry-related issues api topology labels May 16, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

Caution

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

⚠️ Outside diff range comments (1)
src/core/algorithms/flips.rs (1)

822-838: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Local cavity validation can silently accept Unassigned neighbor slots.

Using neighbor_keys() here collapses slot state, so None skips both boundary and potentially unassigned entries. In FlipValidationScope::LocalCavity, that can let partially wired trial cells pass and be committed.

Suggested fix
-    let Some(neighbors) = cell.neighbor_keys() else {
+    let Some(neighbor_slots) = cell.neighbor_slots() else {
         return Ok(());
     };
-    if neighbors.len() != D + 1 {
+    if neighbor_slots.len() != D + 1 {
         return Err(TdsValidationFailure::InvalidNeighbors {
             reason: NeighborValidationError::LengthMismatch {
-                actual: neighbors.len(),
+                actual: neighbor_slots.len(),
                 expected: D + 1,
                 context: "flip trial neighbor validation".to_string(),
             },
         });
     }

-    for (facet_idx, neighbor_key_opt) in neighbors.enumerate() {
-        let Some(neighbor_key) = neighbor_key_opt else {
-            continue;
-        };
+    for (facet_idx, slot) in neighbor_slots.enumerate() {
+        let neighbor_key = match slot {
+            NeighborSlot::Neighbor(key) => key,
+            NeighborSlot::Boundary => continue,
+            NeighborSlot::Unassigned => {
+                return Err(TdsValidationFailure::InvalidNeighbors {
+                    reason: NeighborValidationError::Other {
+                        message: format!(
+                            "flip trial cell {cell_key:?} has unassigned neighbor slot at facet {facet_idx}"
+                        ),
+                    },
+                });
+            }
+        };

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 leaving the triangulation inconsistent”.

🤖 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/algorithms/flips.rs` around lines 822 - 838, The validation
currently uses cell.neighbor_keys(), which collapses slot state so Unassigned
entries and boundary None are indistinguishable, allowing partially wired trial
cells to pass in FlipValidationScope::LocalCavity; change the check to iterate
the raw neighbor slots (e.g., cell.neighbor_slots() or the equivalent API that
preserves slot state) and explicitly treat Unassigned slots as a validation
failure in the LocalCavity path (returning an appropriate TdsValidationFailure
instead of skipping), while still permitting true boundary None where intended;
update the loop that currently matches let Some(neighbor_key) = neighbor_key_opt
to instead inspect each slot's enum/state and error on Unassigned to prevent
committing invalid flips.
🧹 Nitpick comments (1)
src/core/triangulation.rs (1)

8375-8377: ⚡ Quick win

Make these boundary-state assertions explicit.

These macros still go through cell.neighbors() / Option<CellKey>, so they can't distinguish Boundary from Unassigned, and the if let Some(...) makes the check vacuous when the buffer is absent. That leaves the new neighbor-slot contract largely untested across D=2..5.

Suggested assertion shape
-                    if let Some(mut neighbors) = cell.neighbors() {
-                        assert!(neighbors.all(|n| n.is_none()),
-                            "{}D: Initial simplex should have no neighbors (all boundary)", $dim);
-                    }
+                    let mut slots = cell
+                        .neighbor_slots()
+                        .expect("initial simplex should expose explicit neighbor-slot state");
+                    assert!(slots.all(|slot| slot.is_boundary()),
+                        "{}D: Initial simplex should mark every facet as Boundary", $dim);

Also applies to: 9679-9681

🤖 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/triangulation.rs` around lines 8375 - 8377, The current checks call
cell.neighbors() and assert that Option<CellKey> slots are None, which doesn't
distinguish the new NeighborSlot states (Boundary vs Unassigned) and the `if let
Some(...)` makes the assertion vacuous when the neighbor buffer is absent;
update the assertions to read the raw neighbor-slot buffer and explicitly assert
each slot equals NeighborSlot::Boundary (or the intended variant) rather than
checking Option<CellKey>, e.g. use the API that returns the NeighborSlot values
(or index into cell.neighbor_slots / cell.neighbors_raw) and assert equality
against NeighborSlot::Boundary for the initial simplex in
triangulation::initialize (the block around cell.neighbors()) and replicate the
same explicit NeighborSlot::Boundary checks in the other occurrence around lines
9679-9681 so the contract is actually tested across D=2..5.
🤖 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 `@src/core/cell.rs`:
- Around line 948-960: The new neighbors buffer must not be prefilled with
Boundary slots; change ensure_neighbors_buffer_mut to initialize the buffer with
the "unassigned" variant so partially-wired cells are visible — in the closure
that currently does buffer.resize(D + 1, NeighborSlot::Boundary) replace the
filler with the unassigned slot (e.g. NeighborSlot::Unassigned or the
UnassignedNeighborSlot variant used by your NeighborSlot enum) so new
NeighborBuffer entries start as unassigned; keep the debug_assert and len D+1
invariant intact.
- Around line 937-946: The helper set_neighbors_from_keys currently accepts any
iterator and installs a NeighborBuffer of arbitrary length; change it to
validate the neighbor arity equals the expected D + 1 before mutating self:
collect the iterator into a temporary NeighborBuffer (using
NeighborSlot::from_neighbor_key), check its length against the cell's required
neighbor count (the D+1 arity for this Cell), and if it does not match return an
explicit error (e.g., Result::Err with a new InvalidNeighborArity error) instead
of setting self.neighbors; only assign self.neighbors = Some(slots) when the
arity check passes. Use the function name set_neighbors_from_keys, types
NeighborBuffer, NeighborSlot, CellKey and the existing self.neighbors field to
locate and apply this change.

In `@src/core/tds.rs`:
- Around line 3652-3653: The star-walk fast path currently only fallbacks when
the seed cell lacks neighbors; update the logic in the start_cell traversal (the
code using start_cell.contains_vertex, start_cell.neighbor_slots(),
neighbor_keys(), and neighbor_slots() checks) so that any time a visited cell
has no neighbor buffer or contains an Unassigned slot the routine immediately
returns fallback_scan() instead of continuing and returning a partial star;
apply the same change to the other traversal block referenced around the
neighbor iteration (the region covering the logic near lines handling
neighbor_keys() between the current start and the block at the 3670-3704 region)
so that remove_vertex() is only called when the full, fully-wired star is
guaranteed.
- Around line 6056-6080: The current check uses
cell.neighbor_key(facet_index).flatten(), which collapses Unassigned and
Boundary into the same case and allows uninitialized boundary slots; instead,
fetch the raw NeighborSlot (use the non-flattened neighbor_key result),
explicitly match on its variants, and if it is Unassigned return an appropriate
TdsError::InvalidNeighbors (rejecting uninitialized boundary facets) while
preserving the existing handling for Boundary (including the periodic
self-adjacency path via Self::allows_periodic_self_neighbor) and for real
neighbor keys; update the logic around neighbor_key, neighbor == cell_key, and
the two existing NeighborValidationError branches to use this explicit match.

In `@src/core/triangulation.rs`:
- Around line 2013-2020: cell_neighbors currently yields every stored
Some(CellKey) even if the key points to a non-existent cell; update
cell_neighbors to filter out dangling neighbor keys by checking existence with
self.tds.contains_cell(key) before yielding them (similar to the guards used in
build_adjacency_index() and traverse_cell_neighbor_graph()). Locate the method
cell_neighbors (which calls self.tds.cell(c).and_then(Cell::neighbors)...) and
insert a filter step that only passes through neighbor keys where
self.tds.contains_cell(neighbor_key) is true, ensuring only existing neighbors
are exposed.

---

Outside diff comments:
In `@src/core/algorithms/flips.rs`:
- Around line 822-838: The validation currently uses cell.neighbor_keys(), which
collapses slot state so Unassigned entries and boundary None are
indistinguishable, allowing partially wired trial cells to pass in
FlipValidationScope::LocalCavity; change the check to iterate the raw neighbor
slots (e.g., cell.neighbor_slots() or the equivalent API that preserves slot
state) and explicitly treat Unassigned slots as a validation failure in the
LocalCavity path (returning an appropriate TdsValidationFailure instead of
skipping), while still permitting true boundary None where intended; update the
loop that currently matches let Some(neighbor_key) = neighbor_key_opt to instead
inspect each slot's enum/state and error on Unassigned to prevent committing
invalid flips.

---

Nitpick comments:
In `@src/core/triangulation.rs`:
- Around line 8375-8377: The current checks call cell.neighbors() and assert
that Option<CellKey> slots are None, which doesn't distinguish the new
NeighborSlot states (Boundary vs Unassigned) and the `if let Some(...)` makes
the assertion vacuous when the neighbor buffer is absent; update the assertions
to read the raw neighbor-slot buffer and explicitly assert each slot equals
NeighborSlot::Boundary (or the intended variant) rather than checking
Option<CellKey>, e.g. use the API that returns the NeighborSlot values (or index
into cell.neighbor_slots / cell.neighbors_raw) and assert equality against
NeighborSlot::Boundary for the initial simplex in triangulation::initialize (the
block around cell.neighbors()) and replicate the same explicit
NeighborSlot::Boundary checks in the other occurrence around lines 9679-9681 so
the contract is actually tested across D=2..5.
🪄 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: 40e3269a-bfb2-4c9d-9fdb-b8dca5be8ee4

📥 Commits

Reviewing files that changed from the base of the PR and between 526583c and 69ae38f.

📒 Files selected for processing (25)
  • benches/PERFORMANCE_RESULTS.md
  • benches/ci_performance_suite.rs
  • examples/delaunayize_repair.rs
  • examples/diagnostics.rs
  • examples/pachner_roundtrip_4d.rs
  • examples/topology_editing_2d_3d.rs
  • scripts/benchmark_utils.py
  • scripts/tests/test_benchmark_utils.py
  • src/core/algorithms/flips.rs
  • src/core/algorithms/incremental_insertion.rs
  • src/core/algorithms/locate.rs
  • src/core/algorithms/pl_manifold_repair.rs
  • src/core/cell.rs
  • src/core/tds.rs
  • src/core/triangulation.rs
  • src/core/util/delaunay_validation.rs
  • src/core/vertex.rs
  • src/triangulation/delaunay.rs
  • src/triangulation/flips.rs
  • tests/delaunay_incremental_insertion.rs
  • tests/delaunay_repair_fallback.rs
  • tests/delaunayize_workflow.rs
  • tests/prelude_exports.rs
  • tests/proptest_serialization.rs
  • tests/proptest_tds.rs

Comment thread src/core/cell.rs
Comment thread src/core/cell.rs
Comment thread src/core/tds.rs Outdated
Comment thread src/core/tds.rs Outdated
Comment thread src/core/triangulation.rs
- Reject unassigned TDS neighbor slots during validation and flip trials instead of treating them as boundary facets.
- Require neighbor-buffer arity before installation, assign explicit boundary slots for initial simplexes, and filter dangling public neighbor keys.
- Cache same-machine performance-regression baselines by ref, commit, and Rust compiler for perf-no-regressions.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

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 `@src/core/util/delaunay_validation.rs`:
- Around line 545-546: The code currently collapses neighbor slot state via
neighbor_keys().map_or_else(NeighborBuffer::new, Iterator::collect) which loses
the typed slot enum (Boundary vs Unassigned) so DelaunayViolationDetail cannot
distinguish hull facets from missing wiring; change these paths to preserve and
transport the actual slot enum (the typed neighbor-slot variant) instead of
converting to Option<CellKey>, update the construction of the NeighborBuffer
(and analogous code around the other occurrence near lines 749-767) to accept
and store the typed enum values, and adjust the DelaunayViolationDetail
rendering/debug dump to explicitly include the slot variant
(Boundary/Unassigned/Assigned) when emitting diagnostics rather than relying on
neighbor_keys().
🪄 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: 704748fe-0678-4b0f-96a8-e0163106dde6

📥 Commits

Reviewing files that changed from the base of the PR and between 69ae38f and c13e7c9.

📒 Files selected for processing (12)
  • docs/dev/commands.md
  • docs/dev/tooling-alignment.md
  • justfile
  • scripts/benchmark_utils.py
  • scripts/tests/test_benchmark_utils.py
  • src/core/algorithms/flips.rs
  • src/core/algorithms/incremental_insertion.rs
  • src/core/algorithms/locate.rs
  • src/core/cell.rs
  • src/core/tds.rs
  • src/core/triangulation.rs
  • src/core/util/delaunay_validation.rs
✅ Files skipped from review due to trivial changes (2)
  • docs/dev/tooling-alignment.md
  • docs/dev/commands.md
🚧 Files skipped from review as they are similar to previous changes (6)
  • src/core/algorithms/locate.rs
  • src/core/cell.rs
  • src/core/algorithms/flips.rs
  • src/core/triangulation.rs
  • src/core/algorithms/incremental_insertion.rs
  • src/core/tds.rs

Comment thread src/core/util/delaunay_validation.rs Outdated
- Add a large-scale smoke recipe for quick 2D-5D pre-push performance checks.
- Compare local ref baselines by total matched benchmark time while still reporting individual regressions and improvements.
- Split release and worktree comparison reports into explicit filenames.
- Add citation metadata validation to normal configuration linting.
- Preserve raw neighbor slot state in Delaunay violation diagnostics and expose it through the diagnostics prelude.
- Refresh README, workflow, and benchmark documentation for the updated validation and performance workflows.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
justfile (1)

953-953: ⚡ Quick win

Consider passing TOML filenames via argv instead of embedding in Python source.

Embedding {} directly into the python -c string would be brittle for filenames containing quotes or escape characters. While no tracked TOML files currently have such names, using sys.argv[1] defensively prevents future failures.

Suggested fix
-        printf '%s\0' "${files[@]}" | xargs -0 -I {} uv run python -c "import tomllib; tomllib.load(open('{}', 'rb')); print('{} is valid TOML')"
+        printf '%s\0' "${files[@]}" | xargs -0 -n1 uv run python -c 'import sys, tomllib; p = sys.argv[1]; tomllib.load(open(p, "rb")); print(f"{p} is valid TOML")'
🤖 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 `@justfile` at line 953, Replace embedding the filename into the inline Python
code with passing it as an argv to Python: change the xargs call so the {} is
provided as a program argument (after the -c script) and update the python -c
string to import sys and tomllib, call tomllib.load(open(sys.argv[1], 'rb')) and
print sys.argv[1] + " is valid TOML" (or use an f-string) instead of referencing
'{}' inside the source; this uses sys.argv[1] and tomllib.load to avoid brittle
quoting issues.
🤖 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.

Nitpick comments:
In `@justfile`:
- Line 953: Replace embedding the filename into the inline Python code with
passing it as an argv to Python: change the xargs call so the {} is provided as
a program argument (after the -c script) and update the python -c string to
import sys and tomllib, call tomllib.load(open(sys.argv[1], 'rb')) and print
sys.argv[1] + " is valid TOML" (or use an f-string) instead of referencing '{}'
inside the source; this uses sys.argv[1] and tomllib.load to avoid brittle
quoting issues.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 128a2f41-430c-44b3-87dc-f8d3f19fab3b

📥 Commits

Reviewing files that changed from the base of the PR and between c13e7c9 and 2feb6a0.

📒 Files selected for processing (16)
  • .github/workflows/benchmarks.yml
  • .gitignore
  • CITATION.cff
  • README.md
  • benches/README.md
  • docs/code_organization.md
  • docs/dev/commands.md
  • docs/dev/tooling-alignment.md
  • docs/workflows.md
  • justfile
  • scripts/README.md
  • scripts/benchmark_utils.py
  • scripts/tests/test_benchmark_utils.py
  • src/core/util/delaunay_validation.rs
  • src/lib.rs
  • tests/prelude_exports.rs
✅ Files skipped from review due to trivial changes (8)
  • .gitignore
  • docs/workflows.md
  • CITATION.cff
  • docs/code_organization.md
  • scripts/README.md
  • README.md
  • benches/README.md
  • docs/dev/commands.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/prelude_exports.rs

@acgetchell acgetchell merged commit da30293 into main May 17, 2026
21 checks passed
@acgetchell acgetchell deleted the refactor/387-tds-mutation-boundaries branch May 17, 2026 01:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api breaking change documentation Improvements or additions to documentation enhancement New feature or request geometry Geometry-related issues rust Pull requests that update rust code topology

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor!: encapsulate TDS neighbor and incident-cell mutation

1 participant