Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 4 additions & 75 deletions .github/workflows/codacy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,9 @@ jobs:
rsync -a --delete --exclude '.git' ./ "$CODACY_WORKDIR/"

# Execute Codacy Analysis CLI with one selected tool per matrix entry.
# Opengrep reads the repository-owned rules from semgrep.yaml; broad
# default Semgrep/Opengrep packs remain disabled.
# Opengrep should mirror repository-owned rules from semgrep.yaml. The
# SARIF splitter below defensively drops any default Codacy/OpenGrep
# findings whose rule IDs do not belong to this repository.
- name: Run Codacy Analysis CLI
# Cap Codacy runtime so a hung analyzer does not consume the full job timeout.
timeout-minutes: 20
Expand All @@ -98,79 +99,7 @@ jobs:
- name: Split SARIF runs for upload
run: |
set -euo pipefail

python3 <<'PY'
import copy
import json
import os
import re
import sys
from pathlib import Path

source = Path(os.environ["CODACY_SARIF"])
out_dir = Path(os.environ["RUNNER_TEMP"]) / "codacy-sarif"

if not source.is_file() or source.stat().st_size == 0:
sys.exit(f"Codacy did not produce a SARIF file at {source}")

try:
sarif = json.loads(source.read_text(encoding="utf-8"))
except json.JSONDecodeError as exc:
raise SystemExit(f"Codacy produced invalid SARIF JSON: {exc}") from exc

runs = sarif.get("runs")
if not isinstance(runs, list):
sys.exit("Codacy SARIF did not contain a runs array")
if not runs:
print("Codacy SARIF did not contain any runs to upload")

out_dir.mkdir(parents=True, exist_ok=True)
for stale in out_dir.glob("*.sarif"):
stale.unlink()

def slug(value: str) -> str:
normalized = re.sub(r"[^A-Za-z0-9_.-]+", "-", value.strip().lower())
return normalized.strip("-") or "unknown"

seen_categories: dict[str, int] = {}
uploadable_count = 0
for index, run in enumerate(runs, start=1):
rules = run.get("tool", {}).get("driver", {}).get("rules")
results = run.get("results")
if not rules and not results:
print(f"Skipping empty SARIF run {index} with no rules or results")
continue

run_copy = copy.deepcopy(run)
tool = run_copy.get("tool", {}).get("driver", {}).get("name")
base_category = f"codacy-{slug(str(tool or f'run-{index}'))}"
seen_categories[base_category] = seen_categories.get(base_category, 0) + 1
suffix = seen_categories[base_category]
category = base_category if suffix == 1 else f"{base_category}-{suffix}"

automation = run_copy.get("automationDetails")
if not isinstance(automation, dict):
automation = {}
automation["id"] = category
run_copy["automationDetails"] = automation

split_sarif = {key: value for key, value in sarif.items() if key != "runs"}
split_sarif.setdefault("$schema", "https://json.schemastore.org/sarif-2.1.0.json")
split_sarif.setdefault("version", "2.1.0")
split_sarif["runs"] = [run_copy]

out_file = out_dir / f"{index:02d}-{category}.sarif"
out_file.write_text(json.dumps(split_sarif, indent=2), encoding="utf-8")
print(f"Wrote {out_file} with category {category}")
uploadable_count += 1

with Path(os.environ["GITHUB_ENV"]).open("a", encoding="utf-8") as env_file:
env_file.write(f"CODACY_SPLIT_SARIF_DIR={out_dir}\n")
env_file.write(f"CODACY_HAS_UPLOADABLE_SARIF={'true' if uploadable_count else 'false'}\n")

if uploadable_count == 0:
print("No non-empty Codacy SARIF runs to upload")
PY
python3 scripts/ci/filter_codacy_sarif.py "$CODACY_SARIF" "$RUNNER_TEMP/codacy-sarif"

- name: Upload split SARIF files
if: env.CODACY_HAS_UPLOADABLE_SARIF == 'true'
Expand Down
12 changes: 6 additions & 6 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -261,14 +261,14 @@ in practice; when in doubt, favour the invariant over the convenient edit.
`src/topology/manifold.rs` and `src/topology/characteristics/`.
- Repair paths (`repair_delaunay_with_flips`, `repair_facet_oversharing`,
`delaunayize_by_flips`) bound their work via explicit budgets
(`max_flips`, `max_iterations`, `max_cells_removed`) and surface
(`max_flips`, `max_iterations`, `max_simplices_removed`) and surface
non‑convergence as a typed error — never by logging and proceeding.

### Validation layering

The library exposes four validation levels, each a superset of the last:

1. **Level 1 — elements**: individual cells, vertices, facets are
1. **Level 1 — elements**: individual simplices, vertices, facets are
internally consistent (dimensions, UUIDs, coordinate finiteness).
2. **Level 2 — structure**: adjacency pointers and neighbour links form a
valid incidence graph; no dangling keys.
Expand Down Expand Up @@ -310,7 +310,7 @@ degenerate input, and tests under `tests/proptest_sos.rs` enforce that.
### Composability

- Const‑generic `D` on every core type (`DelaunayTriangulation<K, U, V, D>`,
`Tds<T, U, V, D>`, `Cell<T, U, V, D>`, `Vertex<T, U, D>`, `Point<T, D>`).
`Tds<T, U, V, D>`, `Simplex<T, U, V, D>`, `Vertex<T, U, D>`, `Point<T, D>`).
No runtime dimension.
- Per‑simplex data is stack‑allocated (`[T; D]` coordinates,
`SmallBuffer<VertexKey, MAX_PRACTICAL_DIMENSION_SIZE>`). The
Expand All @@ -330,10 +330,10 @@ degenerate input, and tests under `tests/proptest_sos.rs` enforce that.
for documented, debug‑only precondition violations; library code in
`src/` must not panic on user input.
- Borrow by default (`&T`, `&mut T`, `&[T]`); return borrowed views where
possible. `FacetView`, `AdjacencyIndex`, and the `cells()`/`vertices()`
possible. `FacetView`, `AdjacencyIndex`, and the `simplices()`/`vertices()`
iterators are examples.
- Type and function names match the textbook vocabulary: `Triangulation`,
`Vertex`, `Cell`, `Facet`, `Ridge`, `InSphere`, `Orientation`,
`Vertex`, `Simplex`, `Facet`, `Ridge`, `InSphere`, `Orientation`,
`insphere`, `circumcenter`, `circumradius`. Avoid Rust‑ecosystem
abstractions that obscure the math.
- Use `tracing::{debug,info,warn,error}!` for committed diagnostics
Expand Down Expand Up @@ -392,7 +392,7 @@ degenerate input, and tests under `tests/proptest_sos.rs` enforce that.
- Unit tests cover known values, error paths, and dimension‑generic
correctness. Dimension‑generic tests **must cover D=2 through D=5**
whenever feasible; use `pastey` macros to generate per‑dimension tests
(see `src/core/cell.rs`, `src/core/tds.rs` for patterns).
(see `src/core/simplex.rs`, `src/core/tds.rs` for patterns).
- Proptests under `tests/proptest_*.rs` cover algebraic and
topological invariants — round‑trips, Euler characteristic, orientation
sign agreement, SoS consistency — not just "does it not panic".
Expand Down
13 changes: 7 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ The project uses comprehensive CI workflows:
- **Code Quality** (`.github/workflows/rust-clippy.yml`): Strict linting with SARIF upload
- **CodeRabbit** (`.coderabbit.yml`): PR review comments for curated quality feedback
- **Codacy** (`.codacy.yml`): Curated PR quality feedback and duplication/complexity metrics
- **Codacy SARIF mirror** (`.github/workflows/codacy.yml`): Markdownlint-only SARIF upload
- **Codacy SARIF mirror** (`.github/workflows/codacy.yml`): Repository-owned Opengrep SARIF upload
- **Coverage** (`.github/workflows/codecov.yml`): Test coverage tracking with 5-minute per-test timeout

All PRs must pass CI checks before merging.
Expand All @@ -569,14 +569,15 @@ tool configuration, but Codacy does not use that file to turn tools on or off.
- **Configuration**: `.codacy.yml` in the project root
- **Source of Truth**: Treat the tool lists below as a snapshot; verify current enablement in
Codacy project settings -> Tools / Code Patterns or Codacy configuration sync before relying on them
- **Enabled Tools**: Markdownlint, Ruff, ShellCheck, duplication, and advisory Lizard
- **Enabled Tools**: Markdownlint, Ruff, ShellCheck, repository-owned Opengrep, duplication, and advisory Lizard
- **Disabled Tools**: Bandit, Prospector, Pylint, broad Opengrep, Trivy, Jackson Linter, and Spectral
- **Documentation Analysis**: Markdownlint uses `.markdownlint.json`
- **Python Analysis**: Ruff uses `pyproject.toml`
- **Local/CI Analysis**: Rust, Python, shell, YAML, TOML, JSON, and GitHub Actions checks run through `just check`
- **Security Analysis**: Uses CodeQL and cargo-audit rather than Codacy's broader engine set
- **Code Scanning Mirror**: `.github/workflows/codacy.yml` runs Markdownlint only so Codacy's maintainability
findings stay in PR feedback instead of GitHub Code Scanning
- **Code Scanning Mirror**: `.github/workflows/codacy.yml` uploads only repository-owned Opengrep
findings whose rule IDs start with `delaunay.` so Codacy's default maintainability findings stay in
PR feedback instead of GitHub Code Scanning

**Key Benefits:**

Expand Down Expand Up @@ -648,7 +649,7 @@ fix(geometry): handle NaN coordinates in point validation
fix: resolve memory leak in vertex insertion

# Performance
perf(core): optimize Bowyer-Watson algorithm with cell caching
perf(core): optimize Bowyer-Watson algorithm with simplex caching
perf: reduce allocations in neighbor assignment

# Breaking changes
Expand Down Expand Up @@ -721,7 +722,7 @@ algorithm layer. Do not make `crate::core` public or add a broad
`delaunay::core` facade. The public low-level surface should stay explicit and
workflow-oriented:

- `delaunay::tds` for cells, facets, vertex keys, TDS validation, and generic
- `delaunay::tds` for simplices, facets, vertex keys, TDS validation, and generic
triangulation data structures
- `delaunay::collections` for collection aliases, small buffers, and secondary
maps
Expand Down
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ keywords = [ "delaunay", "triangulation", "geometry", "convex-hull", "simplicial
categories = [ "algorithms", "mathematics", "science" ]
readme = "README.md"
include = [
"/Cargo.lock",
"/Cargo.toml",
"/CITATION.cff",
"/LICENSE",
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ complete technical background.

## ✨ Features

- [x] Copyable data types associated with vertices and cells (integers,
floats, chars, custom enums), plus `CellSecondaryMap` and
- [x] Copyable data types associated with vertices and simplices (integers,
floats, chars, custom enums), plus `SimplexSecondaryMap` and
`VertexSecondaryMap` aliases for caller-owned key-indexed algorithm state
- [x] D-dimensional [Delaunay triangulations]
- [x] D-dimensional [Convex hulls]
Expand Down Expand Up @@ -137,7 +137,7 @@ complete technical background.
- [x] 4-level validation hierarchy (element validity → TDS structural
validity → manifold topology → Delaunay property), including full
diagnostics via `validation_report`
- [x] Coherent combinatorial orientation validation/normalization for cells,
- [x] Coherent combinatorial orientation validation/normalization for simplices,
maintaining oriented simplicial complexes
- [x] Typed construction, insertion, TDS, topology, validation, and repair
errors that preserve source context for callers and diagnostics
Expand Down Expand Up @@ -183,7 +183,7 @@ Choose the smallest prelude that matches the task:
| Construction telemetry diagnostics | `use delaunay::prelude::triangulation::diagnostics::*` |
| Construction validation cadence/policy | `use delaunay::prelude::triangulation::validation::*` |
| Hilbert ordering and quantization utilities | `use delaunay::prelude::ordering::*` |
| Low-level TDS cells, facets, keys, and validation reports | `use delaunay::prelude::tds::*` |
| Low-level TDS simplices, facets, keys, and validation reports | `use delaunay::prelude::tds::*` |
| Collection aliases and small buffers | `use delaunay::prelude::collections::*` |
| Topology validation and Euler characteristic helpers | `use delaunay::prelude::topology::validation::*` |
| Topological spaces and topology traits | `use delaunay::prelude::topology::spaces::*` |
Expand Down Expand Up @@ -286,7 +286,7 @@ For the full periodic image-point method (Phase 2), see the

| Level | What is validated | Primary API |
|---|---|---|
| 1 | Element validity (vertex/cell primitives) | `dt.validate()` / `dt.validation_report()` |
| 1 | Element validity (vertex/simplex primitives) | `dt.validate()` / `dt.validation_report()` |
| 2 | TDS structural validity (keys, incidences, neighbors) | `dt.tds().is_valid()` |
| 3 | Manifold topology (link checks, Euler/topological consistency) | `dt.as_triangulation().is_valid()` |
| 4 | Delaunay property (empty-circumsphere via local predicates) | `dt.is_valid()` |
Expand Down Expand Up @@ -544,7 +544,7 @@ Portions of this library were developed with the assistance of these AI tools:
[Hilbert curve]: https://en.wikipedia.org/wiki/Hilbert_curve
[exact predicates]: docs/numerical_robustness_guide.md
[Simulation of Simplicity]: docs/numerical_robustness_guide.md#simulation-of-simplicity-sos
[Secondary maps]: docs/workflows.md#builder-api-auxiliary-vertex-and-cell-data
[Secondary maps]: docs/workflows.md#builder-api-auxiliary-vertex-and-simplex-data
[Validation Guide]: docs/validation.md
[ChatGPT]: https://openai.com/chatgpt
[Claude]: https://www.anthropic.com/claude
Expand Down
2 changes: 1 addition & 1 deletion REFERENCES.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ These references ensure the library's geometric computations are mathematically
## Mesh Quality Metrics

These references inform the geometric quality measures used for evaluating simplex quality
and selecting high-quality cells during triangulation repair.
and selecting high-quality simplices during triangulation repair.

### Quality Measures for Simplicial Meshes

Expand Down
2 changes: 1 addition & 1 deletion benches/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ large-scale scaling workload and the deeper profiling diagnostics:
- construction through the default batch construction path
- process RSS deltas during construction
- memory allocation profiling with the optional `count-allocations` feature
- neighbor queries, vertex iteration, and cell iteration
- neighbor queries, vertex iteration, and simplex iteration
- circumsphere query latency
- algorithmic bottlenecks
- validation component costs
Expand Down
Loading
Loading