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
116 changes: 82 additions & 34 deletions docs/KNOWN_ISSUES_4D.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,71 @@

## Status (v0.7.5)

### Current issues

#### 4D+ bulk construction failures

Large-scale 4D bulk construction can produce Delaunay-validation failures on
adversarial/degenerate point sets, even when local repair steps appear to succeed.
### Re-verified on 2026-04-23 (release mode)

**Severity:** High (correctness)
**Affects:** primarily large 4D bulk runs (typically 100+ vertices)
**Recommended workaround:** prefer incremental insertion for production 4D workloads
These release-mode reruns supersede the old 35-point 3D and 100-point 4D
correctness failures described below:

**#204 findings (v0.7.4):** 4D 100-point batch construction (release mode,
seed `0x9B7786C999C56A16`, ball radius=100) inserts only **12 of 100 vertices**;
88 are skipped as degeneracies. All 88 skips hit the same cell
(`CellKey(29v7)`, vertices `[6v1, 2v1, 9v1, 11v1, 7v1]`) which has negative
geometric orientation. In debug mode, per-insertion PLManifoldStrict validation
of this cell produces repeated warnings that cause extreme slowness (appears as
a hang but is not an algorithmic deadlock). The resulting 12-vertex
triangulation passes L1–L4 validation.
- 3D seed `0xE30C78582376677C` now passes at 35 vertices and at 1000 vertices.
- The 3D 1000-prefix bisect reports no failing prefix for that seed.
- 4D seed `0x9B7786C999C56A16` now inserts 100/100 vertices with zero skips and
passes validation in about 15.4s total wall time.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
- The remaining open part of #204 is the default 4D 3000-point batch run,
which now has progress instrumentation and is clearly a scale/observability
problem rather than the earlier 35/100-point correctness repros.

#### 3D large-scale flip convergence

Flip-based Delaunay repair can enter cycles (oscillating flip sequences that
never converge). The triangulation is topologically valid but may have local
Delaunay violations that flips cannot resolve.
### Current issues

**Severity:** High (correctness)
**Affects:** 3D bulk construction at moderate scale (35+ vertices with default seed)
**Root cause (updated):** predicate degeneracies have been ruled out — the #204
debug runs show `ambiguous=0, predicate_failures=0` in every cycle report. SoS
is working correctly. The remaining cycles are caused by **cavity/topology
interactions** where a sequence of locally legal flips forms a cycle.
#### 4D+ bulk construction retry collapse

Large-scale 4D bulk construction still has a deterministic seeded failure mode
in release mode. The historical 100-point negative-orientation skip repro is
fixed, but larger seeded cases can still enter a skip-heavy path where the
input-order attempt and every shuffled retry finish with a Delaunay-property
violation after repeated conflict-region ridge-fan degeneracies.

**Severity:** High (4D batch-construction correctness / runtime)
**Affects:** seeded 4D batch construction at a few hundred vertices and above;
the default 3000-point large-scale debug harness remains especially expensive
to investigate.
**Recommended workaround:** use release-mode runs and smaller seeded probes when
you need quick iteration; prefer incremental insertion for production 4D
workloads if large batch runtimes are unacceptable.

**Current rechecks (2026-04-23):**

- 4D 100-point batch construction (release
mode, seed `0x9B7786C999C56A16`, ball radius=100) inserts **100 of 100**
vertices, skips **0**, and passes validation in ~15.4s total wall time.
- The same 4D 100-point run now exposes the retry boundary directly: attempt 0
finishes with `inserted=86`, `skipped=14`, then retry 1
(`perturbation_seed=0x34D84963BCC98F21`) inserts **100 of 100** and passes.
- 4D 500-point batch construction (release mode, seed `0xD225B8A07E274AE6`,
ball radius=100, allow skips) is now a smaller deterministic failure repro.
Attempts 0 through 6 all finish invalid after roughly 78–95s each, ending
with `inserted≈266–300`, `skipped≈200–234`, and the same final error:
`Cell violates Delaunay property: cell contains vertex that is inside circumsphere`.
Representative skip samples are dominated by
`Conflict region error: Ridge fan detected: 4 facets share ridge with 3 vertices`.
- 4D 3000-point batch construction (release mode, seed `0xE7E6701F918B07FA`,
ball radius=100) now emits periodic batch-progress summaries. On the first
attempt (`perturbation_seed=0x0`), it had reached:
- processed 100/3000: inserted 81, skipped 19, elapsed ~4.27s
- processed 300/3000: inserted 221, skipped 79, elapsed ~36.11s
- processed 500/3000: inserted 324, skipped 176, elapsed ~94.70s
This run was manually interrupted after capturing the 500-point progress mark.

#### Historical 3D flip-cycle reproducer (now fixed)

The historical 3D flip-cycle seed used by #204/#306 no longer reproduces on
the current branch in release mode.

**Current recheck (2026-04-23):**

- 35-point release run: passes with 35/35 inserted and validation OK
- 1000-point release run: passes with 1000/1000 inserted and validation OK in
~69.6s total wall time
- 1000-prefix bisect: reports no failing prefix for the same seed

**#204 findings (v0.7.4):** the incremental-prefix bisect found a **minimal
failing prefix of 35 vertices** (seed `0xE30C78582376677C`, ball radius=100).
Expand Down Expand Up @@ -127,17 +160,32 @@ DELAUNAY_LARGE_DEBUG_N_4D=100 DELAUNAY_LARGE_DEBUG_ALLOW_SKIPS=1 \
DELAUNAY_LARGE_DEBUG_N_4D=100 DELAUNAY_LARGE_DEBUG_ALLOW_SKIPS=0 \
cargo test --release --test large_scale_debug debug_large_scale_4d \
-- --ignored --nocapture

# 4D 500-point seeded repro (all shuffled retries still fail)
DELAUNAY_BULK_PROGRESS_EVERY=50 \
DELAUNAY_LARGE_DEBUG_N_4D=500 \
DELAUNAY_LARGE_DEBUG_CASE_SEED_4D=0xD225B8A07E274AE6 \
DELAUNAY_LARGE_DEBUG_ALLOW_SKIPS=1 \
cargo test --release --test large_scale_debug debug_large_scale_4d \
-- --ignored --nocapture

# 4D prefix bisect (targets the seeded 500-point repro by default)
DELAUNAY_LARGE_DEBUG_ALLOW_SKIPS=1 \
cargo test --release --test large_scale_debug \
debug_large_scale_4d_incremental_prefix_bisect -- --ignored --nocapture
```

### Recommendations

- **2D:** robust at all tested sizes.
- **3D:** flip-cycle failures start at 35+ vertices with the default seed.
SoS eliminates predicate degeneracies but cavity/topology flip cycles persist.
This is the primary open correctness issue.
- **4D:** batch construction produces a negative-orientation cell early, causing
most subsequent insertions to be skipped. Use incremental insertion for
critical correctness paths.
- **3D:** the historical #306/#204 seed now passes in release mode; continue to
use the large-scale harness as a monitoring tool rather than assuming a 35-point
correctness failure still exists.
- **4D:** the historical 100-point skip repro is fixed, but seeded 500-point
and larger batch runs can still fail after all shuffled retries. Use release
mode for investigation, prefer smaller seeded probes to debug the
`Ridge fan detected` path, and use incremental insertion when you need more
predictable progress at large N.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
- **5D:** experimental; incremental insertion strongly recommended. Exact insphere
predicates are available (5D uses a 7×7 matrix, within the stack limit).
- **6D+:** exact insphere is not available (matrix exceeds stack limit); falls back
Expand Down
45 changes: 32 additions & 13 deletions docs/TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,26 @@ Legend: **🔴 High** · **🟡 Medium** · **🟢 Low**

## 1 · Correctness

### 🔴 3D flip-cycle non-convergence (#306, #204)
### ✅ ~~3D flip-cycle non-convergence (#306, #204)~~ — FIXED

Flip-based Delaunay repair enters cycles at ≥35 vertices (seed-dependent).
SoS eliminates predicate ambiguity; root cause is cavity/topology
interactions. This is the primary open correctness issue.
The historical 35-vertex and 1000-vertex release-mode repros no longer fail on
the current branch. The original seed `0xE30C78582376677C` now passes at 35
vertices, at 1000 vertices, and the 1000-prefix bisect reports no failing
prefix.

**Status:** Diagnostic infrastructure (conflict-region verification,
orientation audits) shipped in #309 and #319. Repair constants unified
across build profiles in #319. Root cause narrowed but not yet fixed.
**Status:** release-mode recheck completed on 2026-04-23; keep #204 focused on
larger-scale monitoring and regression detection rather than the old #306
correctness repro.
Comment thread
coderabbitai[bot] marked this conversation as resolved.

### 🔴 4D bulk construction vertex skipping (#307, #204)
### ✅ ~~4D bulk construction vertex skipping (#307, #204)~~ — FIXED

Batch 4D construction (100 points, specific seed) produces a
negative-orientation cell early, causing 88% of subsequent insertions to be
skipped as degeneracies. Incremental insertion is a viable workaround.
The historical 100-point 4D release-mode repro no longer skips vertices on the
current branch. The original seed `0x9B7786C999C56A16` now inserts all 100
vertices with zero skips and passes validation.

**Status:** Same diagnostic infrastructure as above. Orientation-audit
improvements shipped. Root cause not yet fixed.
**Status:** release-mode recheck completed on 2026-04-23; keep #204 focused on
larger 4D batch-runtime/observability work rather than the old #307
orientation-skip repro.

---

Expand All @@ -53,6 +55,23 @@ optimization needed.
**Status:** profiling can begin; targeted fixes possible if
bottlenecks are clear.

### 🟡 4D large-scale batch runtime / observability (#204)

The known 100-point correctness repro is fixed, but larger seeded 4D release
batch runs still degrade into skip-heavy retries and can fail all shuffled
attempts. The clearest bounded repro is now the 500-point seed
`0xD225B8A07E274AE6`, which spent ~595.9s exhausting attempts 0..6 before
failing with `Cell violates Delaunay property: cell contains vertex that is
inside circumsphere`.

**Status:** 2026-04-23 rechecks confirmed the 100-point case is healthy and the
new retry-boundary instrumentation is working. The 500-point seeded repro shows
attempts ending around `inserted≈266–300`, `skipped≈200–234`, with skip samples
dominated by `Conflict region error: Ridge fan detected: 4 facets share ridge
with 3 vertices`. Continue #204 by tracing that conflict-region ridge-fan path
through the retryable skip logic rather than treating the issue as pure
observability.

---

## 3 · Codebase Complexity
Expand Down
6 changes: 6 additions & 0 deletions docs/dev/debug_env_vars.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ in release builds.
| Variable | Activation | Module | Description |
|---|---|---|---|
| `DELAUNAY_INSERT_TRACE` | presence | `triangulation.rs` | Per-insertion summary (vertex index, location, conflict size, suspicion flags) |
| `DELAUNAY_BULK_PROGRESS_EVERY` | **value** (integer) | `triangulation/delaunay.rs` | Periodic batch progress plus retry-boundary output. |
| `DELAUNAY_DEBUG_CAVITY_REDUCTION_ONCE` | presence | `triangulation.rs` | One-shot trace of the first cavity reduction chain and each re-extraction outcome. |
| `DELAUNAY_DEBUG_RETRYABLE_SKIP` | presence | `triangulation.rs` | Retryable conflict skip trace with attempt and rollback context. |
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
| `DELAUNAY_DEBUG_SHUFFLE` | presence | `triangulation.rs` | Logs vertex shuffle order during batch construction |
| `DELAUNAY_DUPLICATE_METRICS` | presence | `triangulation/delaunay.rs` | Duplicate-detection metrics (spatial hash grid stats) |

Expand All @@ -54,6 +57,7 @@ in release builds.
| `DELAUNAY_DEBUG_CONFLICT_PROGRESS` | presence | `locate.rs` | Periodic progress during large BFS traversals |
| `DELAUNAY_DEBUG_CONFLICT_PROGRESS_EVERY` | **value** (integer) | `locate.rs` | Interval for progress logging (default: dimension-dependent) |
| `DELAUNAY_DEBUG_CONFLICT_VERIFY` | presence | `triangulation.rs` | Brute-force verification of BFS conflict-region completeness with reachability analysis |
| `DELAUNAY_DEBUG_RIDGE_FAN_ONCE` | presence | `locate.rs` | One-shot dump of the first detected ridge fan (ridge vertices, boundary facets, extra cells). |

## Cavity & Hull

Expand Down Expand Up @@ -82,9 +86,11 @@ in release builds.
|---|---|---|---|
| `DELAUNAY_REPAIR_TRACE` | presence | `flips.rs` | Per-flip trace: enqueue, skip, apply, context details |
| `DELAUNAY_REPAIR_DEBUG_FACETS` | presence | `flips.rs` | Facet-level flip skip reasons (degenerate, duplicate, non-manifold, existing simplex) |
| `DELAUNAY_REPAIR_DEBUG_POSTCONDITION_FACET` | presence | `flips.rs` | One-shot snapshot of the first unresolved k=2 facet with last-flip overlap |
| `DELAUNAY_REPAIR_DEBUG_PREDICATES` | presence | `flips.rs` | Insphere classification details for k=2 and k=3 violation checks |
| `DELAUNAY_REPAIR_DEBUG_RIDGE` | presence | `flips.rs` | Ridge context snapshots during k=3 repair |
| `DELAUNAY_REPAIR_DEBUG_RIDGE_LIMIT` | **value** (integer) | `flips.rs` | Maximum ridge debug snapshots (default: 64) |
| `DELAUNAY_REPAIR_DEBUG_RIDGE_MIN_MULTIPLICITY` | **value** (integer) | `flips.rs` | Skip low-multiplicity snapshots; emit when `found >= N` (default: 0). |
| `DELAUNAY_REPAIR_DEBUG_SUMMARY` | presence | `flips.rs` | Per-attempt repair summary (flips, checks, cycles, ambiguous, skips) |

## Predicates & Validation
Expand Down
14 changes: 9 additions & 5 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -215,19 +215,22 @@ coverage-ci:
cargo tarpaulin {{_coverage_base_args}} --out Xml --output-dir coverage -- --skip prop_

debug-large-scale-3d-100:
DELAUNAY_LARGE_DEBUG_N_3D=100 cargo test --test large_scale_debug debug_large_scale_3d -- --ignored --exact --nocapture
DELAUNAY_LARGE_DEBUG_N_3D=100 cargo test --release --test large_scale_debug debug_large_scale_3d -- --ignored --exact --nocapture

debug-large-scale-3d-1000:
DELAUNAY_LARGE_DEBUG_N_3D=1000 cargo test --test large_scale_debug debug_large_scale_3d -- --ignored --exact --nocapture
DELAUNAY_LARGE_DEBUG_N_3D=1000 cargo test --release --test large_scale_debug debug_large_scale_3d -- --ignored --exact --nocapture

debug-large-scale-3d-incremental-bisect total="1000":
DELAUNAY_LARGE_DEBUG_PREFIX_TOTAL={{total}} cargo test --test large_scale_debug debug_large_scale_3d_incremental_prefix_bisect -- --ignored --nocapture
DELAUNAY_LARGE_DEBUG_PREFIX_TOTAL={{total}} cargo test --release --test large_scale_debug debug_large_scale_3d_incremental_prefix_bisect -- --ignored --nocapture

debug-large-scale-4d-incremental-bisect total="500":
DELAUNAY_LARGE_DEBUG_ALLOW_SKIPS=1 DELAUNAY_LARGE_DEBUG_PREFIX_TOTAL={{total}} cargo test --release --test large_scale_debug debug_large_scale_4d_incremental_prefix_bisect -- --ignored --nocapture

debug-large-scale-4d:
cargo test --test large_scale_debug debug_large_scale_4d -- --ignored --nocapture
DELAUNAY_BULK_PROGRESS_EVERY=100 DELAUNAY_LARGE_DEBUG_MAX_RUNTIME_SECS=1800 cargo test --release --test large_scale_debug debug_large_scale_4d -- --ignored --exact --nocapture

debug-large-scale-4d-100:
DELAUNAY_LARGE_DEBUG_N_4D=100 DELAUNAY_LARGE_DEBUG_ALLOW_SKIPS=1 cargo test --test large_scale_debug debug_large_scale_4d -- --ignored --nocapture
DELAUNAY_LARGE_DEBUG_N_4D=100 DELAUNAY_LARGE_DEBUG_ALLOW_SKIPS=1 cargo test --release --test large_scale_debug debug_large_scale_4d -- --ignored --exact --nocapture

# Default recipe shows available commands
default:
Expand Down Expand Up @@ -270,6 +273,7 @@ help-workflows:
@echo " just debug-large-scale-3d-100 # Run large-scale 3D debug harness at 100 points"
@echo " just debug-large-scale-3d-1000 # Run large-scale 3D debug harness at 1000 points"
@echo " just debug-large-scale-3d-incremental-bisect [total] # Bisect failing 3D incremental prefix"
@echo " just debug-large-scale-4d-incremental-bisect [total] # Bisect failing 4D batch prefix"
@echo " just debug-large-scale-4d-100 # Run large-scale 4D debug harness at 100 points"
@echo " just debug-large-scale-4d # Run large-scale 4D debug harness"
@echo ""
Expand Down
Loading
Loading