Skip to content

fix(moves): enforce causal ergodic move contracts - #116

Merged
acgetchell merged 3 commits into
mainfrom
fix/106-ergodic-moves-audit
Jul 21, 2026
Merged

fix(moves): enforce causal ergodic move contracts#116
acgetchell merged 3 commits into
mainfrom
fix/106-ergodic-moves-audit

Conversation

@acgetchell

@acgetchell acgetchell commented Jul 21, 2026

Copy link
Copy Markdown
Owner
  • reject malformed cavities, invalid time assignments, and stale metadata
  • preserve source manifolds and rebuild handle-bearing state after mutation
  • validate complete CDT invariants and literature-derived move deltas
  • document admissibility, inverse relationships, and failure atomicity
  • update the repository UV pin to 0.11.30

Closes #106

Summary by CodeRabbit

  • Bug Fixes
    • Strengthened validation for supported 2+1D ergodic moves, improving early rejection of malformed/incorrect candidates.
    • Tightened move precondition and configuration parameter checks to enhance correctness.
    • Updated transition and command logic so move acceptance relies only on the ergodic move check result.
  • Documentation
    • Added an ergodic move audit guide and linked it from the README.
  • Tests
    • Added a comprehensive doctest-based audit suite covering invariants, expected deltas, reversibility, failure atomicity, and deterministic replays.
  • Chores
    • Bumped the pinned uv version and increased CI test timeout for coverage runs.

- reject malformed cavities, invalid time assignments, and stale metadata
- preserve source manifolds and rebuild handle-bearing state after mutation
- validate complete CDT invariants and literature-derived move deltas
- document admissibility, inverse relationships, and failure atomicity
- update the repository UV pin to 0.11.30

Closes #106
@acgetchell acgetchell self-assigned this Jul 21, 2026
@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7587ba71-e16d-49dd-9fbc-3b188b241d1b

📥 Commits

Reviewing files that changed from the base of the PR and between f4c7df9 and cec15b5.

📒 Files selected for processing (2)
  • include/Ergodic_moves_3.hpp
  • tests/Ergodic_moves_3_audit_test.cpp

Walkthrough

The PR tightens validation for all five supported 2+1D CDT moves, adds post-mutation checks, documents move contracts and deltas, and introduces independent canonicalization, failure-atomicity, inverse-round-trip, and seeded replay tests.

Changes

2+1D CDT ergodic move audit

Layer / File(s) Summary
Move contracts and audit record
docs/ergodic-moves.md, README.md, Justfile, include/Ergodic_moves_3.hpp
Documents move applicability, causal validity, independent deltas, failure atomicity, and audit coverage; updates the pinned uv version.
Causal move applicability
include/Ergodic_moves_3.hpp
Adds finite-edge and cavity validation, strengthens type and timeslice checks, and rejects invalid move sites before mutation.
Post-move invariant gate
include/Ergodic_moves_3.hpp, include/Metropolis.hpp, include/Move_command.hpp
Adds post-mutation validation, checks preserved configuration values and causal correctness, and uses check_move for transition acceptance.
Independent audit validation
tests/Ergodic_moves_3_audit_test.cpp, tests/CMakeLists.txt, .github/workflows/codecov-upload.yml
Adds canonical state comparisons, independent delta and invariant checks, inverse round trips, failure-atomic rejection tests, seeded replay coverage, and an extended CI timeout.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant MoveCommand
  participant MoveStrategy
  participant ErgodicMoves
  MoveCommand->>ErgodicMoves: apply_random_move
  MoveCommand->>ErgodicMoves: check_move(current, result, move_type)
  MoveStrategy->>ErgodicMoves: check_move(current, candidate, move)
  ErgodicMoves-->>MoveCommand: accept or reject result
  ErgodicMoves-->>MoveStrategy: accept or reject candidate
Loading

Possibly related issues

  • Issue 101 — Strengthens invariant and move-applicability validation in overlapping execution paths.
  • Issue 90 — Covers completion and validation of the 2+1D CDT move set.

Possibly related PRs

Poem

Five moves turn through causal space,
Checked before and after place.
Counts align, states return,
Failed paths leave no scars to learn.
Seeded tests watch each turn.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The Justfile uv pin and Codecov workflow timeout/comment changes are unrelated to the linked audit work. Move the tooling and CI updates into a separate PR unless they are required for the audit, to keep this change focused on #106.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the main change: enforcing causal contracts for ergodic moves.
Linked Issues check ✅ Passed The PR adds an independent audit doc and focused tests for all five moves, with stricter move checks and failure-atomic behavior matching #106.
✨ 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 fix/106-ergodic-moves-audit

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

- compare preserved move configuration values by representation to satisfy strict floating-point warnings without weakening drift detection
- allow coverage-instrumented unit tests enough time to complete
coderabbitai[bot]
coderabbitai Bot previously requested changes Jul 21, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (4)
tests/Ergodic_moves_3_audit_test.cpp (2)

301-310: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Keep the invariant audit independent of production predicates.

check_independent_invariants still relies on manifold.is_foliated(), check_vertices(), check_simplices(), and is_correct(). If a move implementation and one of these predicates share the same causal or metadata defect, the audit can pass without detecting it. Make raw TDS, vertex-time, cell-type, and neighbor checks authoritative; treat production predicates only as supplemental diagnostics.

As per path instructions, tests must provide comprehensive coverage.

🤖 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 `@tests/Ergodic_moves_3_audit_test.cpp` around lines 301 - 310, Update
check_independent_invariants to make independent raw TDS, vertex-time,
cell-type, and neighbor validations authoritative, using counts and
triangulation data rather than manifold.is_foliated(), check_vertices(),
check_simplices(), and is_correct(). Retain those production predicates only as
supplemental diagnostics, and ensure the audit comprehensively covers the stated
invariants.

Source: Path instructions


629-836: 🎯 Functional Correctness | 🔵 Trivial | 🏗️ Heavy lift

Exercise post-mutation failure atomicity.

The rejection cases here fail during site selection or preflight. They do not exercise the (2,6)/(6,2) or bistellar-flip paths that mutate a private copy and then reject after a TDS/count validation fails. Add deterministic post-operation failure fixtures and compare the original canonical state afterward.

As per path instructions, tests must provide comprehensive coverage.

🤖 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 `@tests/Ergodic_moves_3_audit_test.cpp` around lines 629 - 836, The existing
rejection tests cover only preflight failures; add deterministic tests for
post-mutation validation failures in the (2,6)/(6,2) and bistellar-flip paths.
Extend the audit scenario using the relevant move helpers, fixtures, and
validation hooks to force TDS or count validation to fail after mutation, then
assert the operation rejects and the original canonical state remains unchanged.
Ensure both mutation paths and their failure-atomic behavior are covered
comprehensively.

Source: Path instructions

include/Ergodic_moves_3.hpp (2)

749-754: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Validate the edge before reading its vertices. is_well_formed_edge only checks the handle shape; find_bistellar_flip_location still dereferences t_edge_candidate.first before any triangulation.tds().is_edge(...) membership check. Move that check ahead of the vertex lookups, or reuse finite_incident_cells here.

🤖 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 `@include/Ergodic_moves_3.hpp` around lines 749 - 754, Update
find_bistellar_flip_location to validate t_edge_candidate against
triangulation.tds().is_edge(...) immediately after the is_well_formed_edge check
and before either vertex(...)->info() lookup. Reuse finite_incident_cells if
that is the established membership-validation path, while preserving the
existing early-return behavior for invalid edges.

81-106: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Reject infinite incident cells here. finite_incident_cells() should return nullopt as soon as any incident cell is infinite; filtering them out lets boundary edges satisfy the size checks in is_32_movable() and find_bistellar_flip_location().

🤖 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 `@include/Ergodic_moves_3.hpp` around lines 81 - 106, Update
finite_incident_cells() to return std::nullopt immediately when any incident
cell is infinite, rather than filtering infinite cells from incident_cells.
Preserve the existing edge validation and successful collection of all finite
incident cells for fully finite edges.
🤖 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 `@tests/Ergodic_moves_3_audit_test.cpp`:
- Around line 850-861: Extend the test case around make_44_fixture and
check_move with a second doctest subcase that changes only foliation_spacing
while preserving initial_radius, using -0.0 in the constructed Manifold and
asserting its representation is retained. Verify after.is_correct() and that
check_move rejects the FOUR_FOUR transition, while keeping the existing
initial_radius coverage unchanged.

---

Outside diff comments:
In `@include/Ergodic_moves_3.hpp`:
- Around line 749-754: Update find_bistellar_flip_location to validate
t_edge_candidate against triangulation.tds().is_edge(...) immediately after the
is_well_formed_edge check and before either vertex(...)->info() lookup. Reuse
finite_incident_cells if that is the established membership-validation path,
while preserving the existing early-return behavior for invalid edges.
- Around line 81-106: Update finite_incident_cells() to return std::nullopt
immediately when any incident cell is infinite, rather than filtering infinite
cells from incident_cells. Preserve the existing edge validation and successful
collection of all finite incident cells for fully finite edges.

In `@tests/Ergodic_moves_3_audit_test.cpp`:
- Around line 301-310: Update check_independent_invariants to make independent
raw TDS, vertex-time, cell-type, and neighbor validations authoritative, using
counts and triangulation data rather than manifold.is_foliated(),
check_vertices(), check_simplices(), and is_correct(). Retain those production
predicates only as supplemental diagnostics, and ensure the audit
comprehensively covers the stated invariants.
- Around line 629-836: The existing rejection tests cover only preflight
failures; add deterministic tests for post-mutation validation failures in the
(2,6)/(6,2) and bistellar-flip paths. Extend the audit scenario using the
relevant move helpers, fixtures, and validation hooks to force TDS or count
validation to fail after mutation, then assert the operation rejects and the
original canonical state remains unchanged. Ensure both mutation paths and their
failure-atomic behavior are covered comprehensively.
🪄 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.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: d9a83ac6-11c0-448f-9421-b6ba7618d79a

📥 Commits

Reviewing files that changed from the base of the PR and between bb53988 and f4c7df9.

📒 Files selected for processing (3)
  • .github/workflows/codecov-upload.yml
  • include/Ergodic_moves_3.hpp
  • tests/Ergodic_moves_3_audit_test.cpp

Comment thread tests/Ergodic_moves_3_audit_test.cpp
Reject boundary and foreign edges before accessing triangulation metadata, and
treat any infinite incident cell as an invalid move site.

Preserve source manifolds when validation rejects post-mutation states for
(2,6), (6,2), and (4,4) transitions.
@acgetchell
acgetchell dismissed coderabbitai[bot]’s stale review July 21, 2026 18:03

All valid findings were addressed in cec15b5. The remaining signed-zero foliation-spacing suggestion was verified to require an invalid acausal manifold state, documented in the thread, and resolved.

@acgetchell
acgetchell merged commit 5b8f723 into main Jul 21, 2026
13 checks passed
@acgetchell
acgetchell deleted the fix/106-ergodic-moves-audit branch July 21, 2026 18:04
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.

Audit and independently validate all 3D CDT ergodic moves

1 participant