Commit Graph

105 Commits

Author SHA1 Message Date
Tarik Moussa
fc77afc55f docs(roadmap): add phase orchestration system mirroring the reviewer audit workflow
All checks were successful
C++ Tests / test-fast (pull_request) Successful in 2m28s
C++ Tests / quality-gates (pull_request) Has been skipped
C++ Tests / test-cgal (pull_request) Has been skipped
Brings doc/roadmap/ to the same operational level as doc/reviewer/ by adding
the two missing structural files and updating existing docs to close the gap
identified in the system review.

New files:
- doc/roadmap/phase-orchestration.md  — master phase table (model assignments,
  session IDs, status, review-gate checklist); mirrors finding-orchestration.md
- doc/roadmap/session-prompts.md      — copy-paste-ready prompts for P1–P4
  (Haiku/Sonnet/Opus) + universal Opus review gate; mirrors reviewer/session-prompts.md

Updated files:
- CLAUDE.md: roadmap section now lists porting-status.md, phase-orchestration.md,
  session-prompts.md; reviewer section adds finding-orchestration.md and
  session-prompts.md; agentic-workflow section has direct "S3 is next / P1 is next"
  entry points so agents don't need to derive the next action from scratch
- doc/roadmap/phases.md: Current-focus table at the top (7 tracks, next session
  per track, gating); cross-links to geometry-central-comparison.md,
  software-landscape.md, complexity.md added in GC and 9b-analytic sections
- doc/roadmap/porting-status.md: snapshot date updated to 2026-05-31 (post S1+S2);
  test count replaced by reference to doc/api/tests.md; §4 gains four new solver
  rows (newton_core refactor, NewtonStatus enum, diagnostics, selectable clamp mode);
  §7 gains four new research-extension rows from S1/S2
- doc/roadmap/research-track.md: header companion-docs section links to
  novelty-statement.md, software-landscape.md, and phase-orchestration.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 00:52:02 +02:00
Tarik Moussa
5f3c6aa0d5 docs(reviewer): add ready-to-paste session prompts (S3–S6 + review gate)
Some checks failed
C++ Tests / test-fast (pull_request) Failing after 1m49s
C++ Tests / quality-gates (pull_request) Has been skipped
C++ Tests / test-cgal (pull_request) Has been skipped
session-prompts.md: one self-contained, copy-paste prompt per pending session,
each naming the model (Sonnet/Haiku/Opus), the findings + audit doc, the
build/test commands, and the branch/push/PR + review-gate workflow.  S6 carries
the G0 precondition.  Linked from finding-orchestration.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 19:44:50 +02:00
Tarik Moussa
c4442a22c3 docs(reviewer): mark S2 CGAL-result follow-up done (957f506)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 19:44:50 +02:00
Tarik Moussa
4f8530628b docs(reviewer): mark S2 (I1/H1/N7) done in the plan + audit banners
Update finding-orchestration.md (master table I1/H1/N7 → , S2 session marked
done with the original plan folded into a <details>), README headline cells +
next-batch pointer (now S3), and the test-coverage / numerical-stability audit
banners.  S2 was implemented directly by Opus in the warm post-refactor session
(commit 90e966a); 301/301 tests green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 19:44:50 +02:00
Tarik Moussa
74d41e99a8 docs(reviewer): update audit status + add finding-orchestration plan
Session 1 (2026-05-31) resolved 26 findings across Sonnet/Haiku/Opus; 298/298
CGAL tests green.  Bring the audit docs in line with reality:

- README.md: G0 banner now records that the original authors were contacted by
  email about porting/relicensing rights (awaiting reply); headline-status cells
  updated per finding; new "Session 1 — implemented" record; link to the plan.
- Per-audit resolution banners (api-performance, numerical-stability,
  input-validation, test-coverage, math-citation, thread-safety) + G0-blocked
  banners (cgal-submission, dependency-license).
- NEW finding-orchestration.md: the meta-plan mapping every finding to a session,
  an implementing model (Haiku/Sonnet/Opus by the "how much must be understood"
  rule), and an Opus review gate after each implementation session.  Records S1
  (done) and lays out S2–S6 so the next session can be picked up cold.

Docs only — no code change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 19:44:50 +02:00
Tarik Moussa
202b9a108d feat(num): N3 selectable scale-floor clamp mode (HardJava | SmoothBarrier)
The hyper-ideal vertex scale b is floored to keep the geometry valid.  The
original clamp `b<0 → 0.01` mirrors the Java oracle but is only C⁰ (in fact
value-discontinuous at b=0): a Newton step crossing the feasibility boundary
hits a kink that can stall convergence (numerical-stability audit N3).

Rather than replace the Java-faithful behaviour (which would break the golden
parity tests), make the floor a selectable mode so BOTH the Java standpoint
and the clean mathematics are available:

- HyperIdealScaleClamp::HardJava (DEFAULT) — the original snap, bit-for-bit
  faithful to HyperIdealFunctional.java → all parity tests unchanged.
- HyperIdealScaleClamp::SmoothBarrier — C¹ softplus floor
  b ↦ floor + softplus_β(b−floor), β = HYPER_IDEAL_SCALE_SHARPNESS (=100);
  ≈ identity away from the floor, smooth across b=0.  Opt-in.

clamp_hyper_ideal_scale centralises the logic (also folds in the N4 nachzügler:
compute_face_angles used a bare 0.01).  The mode threads with a defaulted
trailing parameter through compute_face_angles, face_angles_from_local_dofs,
evaluate_hyper_ideal, the four hyper_ideal_hessian* variants and
newton_hyper_ideal — so every existing call site keeps HardJava behaviour.

Tests (+4): clamp-function C¹/floor/identity contract, mode-equivalence away
from the boundary, and end-to-end SmoothBarrier convergence to the same Java
golden vector (LawsonHyperIdeal).  296/296 CGAL tests pass.
Documented in doc/math/geometry-modes.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 19:44:50 +02:00
Tarik Moussa
51d9844f7a docs(references): M1/M2/M4 citation fixes (audit quick-wins)
M1: Add two missing references used in hyper_ideal_utility:
  - Kolpakov, Mednykh (2006, arXiv math/0603097) — tetrahedron volume w/ one ideal vertex
  - Meyerhoff, Ushijima (2006) — tetrahedron volume w/ three ideal vertices

M2: Clarify BPS publication year: Geometry & Topology 2015 (arXiv 2010)
  - Update references.md to note "first posted 2010"
  - Normalize all code comments from "BPS-2010" → "BPS-2015" (published version)

M4: Standardize citation format in code comments
  - Normalize all "Luo (2004)" / "Luo-2004" / "Luo's 2004" → "Luo 2004"
  - Matches references.md convention: Author Year (no parens/dashes)

282/282 tests pass. Addresses M1, M2, M4 from math-derivation-citation audit.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-05-31 19:44:39 +02:00
Tarik Moussa
b274591aa8 docs(reviewer): aggregate all 12 audits into the index + record decisions
Some checks failed
C++ Tests / test-fast (pull_request) Failing after 1m58s
C++ Tests / quality-gates (pull_request) Has been skipped
C++ Tests / test-cgal (pull_request) Has been skipped
Adds a comprehensive 'External audit documents' section to the reviewer index:
- groups all 12 audits (correctness, API/perf/packaging, robustness)
- surfaces G0 (porting rights) as the cross-cutting release blocker
- records the decisions taken: coverage gate 80/70/90, API naming A1-A5
  (A1-A3 implemented in PR #36, A4-A5 deferred pending G0/G1)
- points a new session at the low-risk quick-win findings

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 10:46:05 +02:00
dc978cf5d3 Merge pull request 'review: usability audit v0.10.0 — all 11 findings resolved' (#34) from review/usability-audit-2026-05-31 into main
Some checks failed
C++ Tests / test-fast (push) Failing after 2m11s
C++ Tests / quality-gates (push) Has been skipped
API Docs / doc-build (push) Has been skipped
Markdown link check / check (push) Has been skipped
Mirror to Codeberg / mirror (push) Successful in 32s
C++ Tests / test-cgal (push) Has been skipped
2026-05-31 08:32:21 +00:00
Tarik Moussa
b213ad2265 docs(reviewer): add math-derivation & citation audit
All checks were successful
C++ Tests / test-fast (pull_request) Successful in 2m23s
C++ Tests / quality-gates (pull_request) Has been skipped
C++ Tests / test-cgal (pull_request) Has been skipped
Checks code/docs against the published mathematics (vs java-port-audit which
checks code vs Java):
- M1: Kolpakov-Mednykh volume formula used in code but missing from references.md
- M2: BPS circle-packing paper cited as '2010' in code vs '2015' in references.md
- M3: post-2023/preprint citations back unimplemented phases — re-verify + clarify
  scope before submission
- M4: no canonical citation-key convention
- M5: large derivations numerically validated but prose unreviewed — expert sign-off

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 10:21:24 +02:00
Tarik Moussa
bad3c4a9ab docs(reviewer): add 4 gap audits — numerical, input-validation, thread-safety, dependency/license
Closes the dimensions the prior audits did not cover:

- numerical-stability: tolerance hierarchy (FD-step vs Newton tol), discontinuous
  clamps, cancellation in cotangent/area, magic constants.
- input-validation: malformed JSON/XML deserialization, NaN/Inf vertex coords on
  load, schema-drift handling.
- thread-safety: no mutable static state (good); undocumented same-mesh concurrency
  contract; Eigen threading.
- dependency-license: existing THIRD-PARTY-LICENSES matrix is sound but predicated
  on the MIT premise that G0 undermines; test meshes have no provenance/license.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 10:21:24 +02:00
Tarik Moussa
7902ae8e2c docs(reviewer): add external audits — test/error-handling, API/perf, CGAL readiness
Three complementary, self-contained audit documents (each actionable by a
fresh session, with file:line, code snippets, fixes, acceptance criteria):

- test-coverage-error-handling-audit: coverage gaps + error-handling robustness;
  agreed gate 80% line / 70% branch / 90% function.
- api-performance-audit: API-naming consistency (A1–A5, decided) + Newton-solver
  performance (B1 block-FD, redundant gradient evals, factorization reuse).
- cgal-submission-readiness-audit: G0 porting-rights blocker (original is
  unlicensed Varylab/TU-Berlin code; this is a derivative work — clarify with
  authors before any license/release), G1 license, layout, concept, manual, tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 10:21:24 +02:00
Tarik Moussa
37b538aae4 docs: Layout2D index semantics, CLI table, CLI roadmap (U9+U10+U11)
Some checks failed
C++ Tests / test-fast (push) Has been cancelled
C++ Tests / test-cgal (push) Has been cancelled
C++ Tests / quality-gates (push) Has been cancelled
API Docs / doc-build (push) Has been cancelled
Markdown link check / check (push) Has been cancelled
C++ Tests / test-fast (pull_request) Successful in 2m10s
C++ Tests / quality-gates (pull_request) Has been skipped
C++ Tests / test-cgal (pull_request) Has been skipped
U9 (layout.hpp + example_layout.cpp)
  Layout2D.uv and .halfedge_uv now have explicit Doxygen docs stating:
    - indexing: v.idx() / h.idx() (raw integer index)
    - length: mesh.number_of_vertices() / number_of_halfedges()
    - precondition: no vertex removal / collect_garbage() after loading
    - access pattern example in the doc comment
  example_layout.cpp: access site comment + static_cast<size_t>(v.idx())

U10 (getting-started.md)
  New 'CLI parameter reference' table (7 rows) added directly below the
  CLI usage examples; cross-references --help as the canonical source

U11 (doc/roadmap/phases.md)
  New Phase 9h 'CLI usability extensions' section inserted before Phase 10:
    9h.1  --tol / --max-iter solver-tuning params  (~30 min, no deps)
    9h.2  -g cp_euclidean / -g inversive_distance  (~2-4 h, needs 9a )
  Each sub-task has effort estimate, implementation sketch, and
  acceptance criteria so a future session can pick it up cold.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 01:51:04 +02:00
Tarik Moussa
ccbfd852b2 docs(examples): use gauge-vertex overload everywhere (U6)
Finding-U6 from doc/reviewer/usability-audit-2026-05-31.md.

The Finding-D fix (external-audit-2026-05-30) added a clean one-call
gauge-vertex overload:
  assign_euclidean_vertex_dof_indices(mesh, maps, gauge_vertex)

But all user-facing code still showed the old verbose manual loop:
  auto vit = mesh.vertices().begin();
  maps.v_idx[*vit++] = -1;
  int idx = 0;
  for (; vit != mesh.vertices().end(); ++vit) maps.v_idx[*vit] = idx++;

Replaced in three places:
  README.md 'Minimal usage' code block
  example_euclidean.cpp Step 3
  example_layout.cpp  pin_first() helper

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 01:49:05 +02:00
Tarik Moussa
d1399ca82f docs: fix stale version, CGAL header, add LOW_MEMORY_BUILD docs (U4+U5+U7+U8)
U4 (README.md:17) — status line: v0.9.0 → v0.10.0, test count 0 → 277

U5 (Discrete_conformal_map.h:6-16) — \file Doxygen block rewritten:
  was: 'provides a single function … Spherical/hyperbolic scheduled for Phase 8b.2'
  now: lists all three discrete_conformal_map_* functions already present,
       plus pointers to the circle-packing companion headers

U7 (getting-started.md) — new 'Mode 4 — Low-memory build' section added
  after Mode 3; shows CONFORMALLAB_LOW_MEMORY_BUILD=ON with -j1 and explains
  the -O0 / no PCH / batch-1 tradeoffs for Raspberry Pi / ≤ 4 GB runners

U8 (README.md compile-time modes) — LOW_MEMORY_BUILD entry added to the
  compile-time workflow code block with a one-line explanation and the
  mandatory -j1 note

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 01:46:08 +02:00
Tarik Moussa
b8d6e23adf docs(contracts): fix three errors in processing-unit contract table (U3)
Finding-U3 from doc/reviewer/usability-audit-2026-05-31.md.

Three concrete errors corrected:

1. check_gauss_bonnet() row (was: implies all map types work)
   → now: 'EuclideanMaps/SphericalMaps only' — HyperIdealMaps overload
     is = delete (compile error since external-audit Finding-B fix)

2. enforce_gauss_bonnet() row (same issue)
   → same restriction note added

3. newton_hyper_ideal() preconditions (was: 'lambda0 initialised')
   → WRONG: HyperIdeal computes lengths from b_v, a_e via zeta functions
     internally; lambda0 plays no role.  Correct precondition:
     'no lambda0 needed · no GB pre-check'
   → Added explanation: strictly convex energy (Springborn 2020 Thm 1.3)
     → Newton converges for any targets without a pre-check

Gauss-Bonnet prose section also updated:
  - Examples now show EuclideanMaps/SphericalMaps explicitly
  - HyperIdeal compile-error note added with the correct hyperbolic
    identity Σ(2π-Θ_v) - Area = 2π·χ and why no pre-check is needed
  - Open-mesh note added (GB identity does not hold for boundary meshes)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 01:44:36 +02:00
Tarik Moussa
b20a835b82 doc(audit): add U10+U11 — CLI parameter docs and extension roadmap
U10: CLI has no parameter reference in README or getting-started.md.
     Documents all 7 current flags with defaults in the audit file so
     a future session can add the table to getting-started.md.

U11: Three useful CLI gaps documented as a roadmap item:
     - --tol / --max-iter: Newton solver tuning, currently hardcoded
     - -g cp_euclidean / -g inversive_distance: Phase-9a models not
       reachable from CLI despite being fully implemented in the library
     Each item has an effort estimate (~30 min / ~2 h) and concrete
     acceptance criteria so a future session can pick it up cold.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 01:40:46 +02:00
Tarik Moussa
02a3745b67 examples: add real conformal-flattening + CGAL-API examples (U1+U2)
Finding-U1 and Finding-U2 from doc/reviewer/usability-audit-2026-05-31.md.

The existing examples (example_euclidean, example_layout, example_hyper_ideal)
all used the "natural theta" pattern which makes x*=0 trivially the
equilibrium — u_v ≈ 0 everywhere, no deformation. A new user following
these examples saw solver output but not conformal geometry.

New: example_flatten.cpp
  - PRIMARY USE CASE: conformally flatten a mesh to the plane
  - Sets Θ_v = 2π for all interior vertices (flat target)
  - Pins boundary vertices (no Gauss-Bonnet check for open meshes)
  - Demonstrates non-trivial u_v (cathead.obj: range ≈ 2.96, 5 Newton iters)
  - Documents the difference from "natural theta" explicitly

New: example_cgal_api.cpp
  - Demonstrates CGAL::discrete_conformal_map_euclidean (Discrete_conformal_map.h)
  - First runnable CGAL public API example; contrast with internal API
  - Documents the "natural theta" default behaviour and explains why u_v=0
  - Explains when to use CGAL API vs internal API

Both examples registered in code/examples/CMakeLists.txt and compile
cleanly with -DWITH_CGAL=ON.

Updated:
  - example_euclidean.cpp: prominent "TESTING CONVENTION" warning
  - example_layout.cpp: same warning on set_natural_theta helper
  - doc/getting-started.md: example_flatten is now the recommended
    "start here" example; note on natural-theta behaviour added

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 01:35:37 +02:00
Tarik Moussa
fb9a15ab4a doc(reviewer): add usability audit 2026-05-31
External documentation and usability review of v0.10.0.
9 findings covering documentation correctness, API usability,
and new-user experience.

Critical:
  U1 — All examples show trivial identity map (natural theta),
       not real conformal flattening — new users see no-op output
  U2 — CGAL public API has zero runnable examples

Medium:
  U3 — contracts.md incorrect: check_gauss_bonnet row missing
       HyperIdeal restriction (deleted overload after Finding-B)
  U4 — README still shows v0.9.0 (current: v0.10.0, 277 tests)
  U5 — Discrete_conformal_map.h header comment describes Phase-8a
       state; all 5 entry functions already implemented
  U6 — New gauge-vertex overload (Finding-D) not reflected in
       README or examples — old verbose loop still shown

Minor:
  U7 — CONFORMALLAB_LOW_MEMORY_BUILD absent from getting-started.md
  U8 — CONFORMALLAB_LOW_MEMORY_BUILD absent from README table
  U9 — Layout2D.uv index semantics undocumented (v.idx() contract)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 01:28:20 +02:00
Tarik Moussa
449c5899c0 ci: re-enable CGAL tests with LOW_MEMORY_BUILD for Raspberry Pi runner
Finding-I from doc/reviewer/external-audit-2026-05-30.md.

Root cause: CGAL+Eigen at -O3 drives cc1plus peak RAM to ~700 MB per
Unity compilation unit (batch size 4) on ARM64.  With the 1600 MB
container limit the 2nd or 3rd TU reliably triggered OOM-kill, so
test-cgal was gated off via `if: false` since 2026-05-26.

Fix: new CMake option CONFORMALLAB_LOW_MEMORY_BUILD=ON applies four
orthogonal memory-saving measures to conformallab_cgal_tests:

  1. -O0 (no debug info): optimizer passes entirely skipped → cc1plus
     peak drops from ~700 MB to ~150-200 MB per TU on ARM64.
     Omitting -g avoids the additional object-file / linker RAM cost.

  2. CONFORMALLAB_USE_PCH=OFF: saves the one-time ~200 MB PCH
     compilation cost; each TU re-parses CGAL headers (fast at -O0).

  3. UNITY_BUILD_BATCH_SIZE=1: one source file per cc1plus invocation,
     removing the "4-file template-explosion" per-unit multiplier.

  4. -Wl,--no-keep-memory (GNU ld): linker releases symbol tables after
     each input file → ~15-25 % less linker RSS.

Verified locally with cmake -DCONFORMALLAB_LOW_MEMORY_BUILD=ON:
  277/277 CGAL tests pass, 31 s runtime (vs 2 s at -O3 — expected;
  tests run 15× slower without optimizer but all correct).

CI workflow changes (cpp-tests.yml):
  - test-cgal re-enabled: `if: github.event_name == 'pull_request'`
  - Configure step adds -DCONFORMALLAB_LOW_MEMORY_BUILD=ON
  - Container memory: 1600m → 2000m (--memory-swap=3000m for 1 GB swap
    headroom), using ~half of the Pi's 3-4 GB while leaving OS margin.

CLAUDE.md updated: new flag added to compile-time options table; CI
status row corrected from DISABLED to active.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 01:17:27 +02:00
Tarik Moussa
59a26123c8 fix(minor): all five MINOR findings — doc, accuracy, and DRY
MINOR-1 (spherical_functional.hpp:426)
  Wrong comment said "second derivative < 0 for a convex functional".
  The spherical energy is *concave* (NSD Hessian); the monotone-f argument
  applies to both convex and concave functionals equally.  Comment rewritten
  to explain the actual physics: increasing scale increases all angles and
  thus reduces Σ G_v.

MINOR-2 (spherical_functional.hpp:494-495)
  Forward finite difference O(ε) → central finite difference O(ε²):
    old: dft = (sum_Gv(t + fd_eps) - ft) / fd_eps
    new: dft = (sum_Gv(t + fd_eps) - sum_Gv(t - fd_eps)) / (2*fd_eps)
  Same cost when the extra sum_Gv(t - fd_eps) replaces the cached ft.

MINOR-3 (euclidean_functional.hpp, spherical_functional.hpp,
         inversive_distance_functional.hpp)
  New header gauss_legendre.hpp centralises the 10-point Gauss-Legendre
  nodes and weights (gl10_nodes() / gl10_weights()).  The three energy
  functions now use the shared accessors instead of duplicated local
  static arrays.

MINOR-4 (euclidean_functional.hpp, spherical_functional.hpp,
         hyper_ideal_functional.hpp, inversive_distance_functional.hpp)
  halfedge_to_index() centralised in conformal_mesh.hpp.  All four local
  aliases (eucl_hidx, spher_hidx, hidx, id_detail::hidx) now delegate to
  it as one-line wrappers; the aliases are kept for now to avoid a larger
  call-site churn, clearly documented as thin wrappers.

MINOR-5 (clausen.hpp:33-38)
  Added a comment above inits() explaining the intentional off-by-one
  return value and how it interacts with csevl() — matching the Java
  Clausen.inits() / csevl() contract.

277/277 CGAL + 26/26 pure-math tests pass, 0 failed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 01:17:27 +02:00
Tarik Moussa
2325328f77 test: add end-to-end skewed-torus and synthetic holonomy Re(τ)<0 tests
Finding-H from doc/reviewer/external-audit-2026-05-30.md
(java-port-audit missing-test item 7).

Guards against a regression where compute_period_matrix reverts to
reduce_to_fundamental_domain (no mirror fold) instead of normalizeModulus
(Finding 6 fix, Java-faithful): such a revert would silently produce
Re(τ) < 0 for lattices where the natural generators give a negative
real part.

Two new tests in test_phase7.cpp:

1. SkewedTorus_ReTauNegativeBeforeNorm_FoldedToPositive
   - New mesh: code/data/off/torus_skewed_4x4.off
     Flat 4×4 torus on parallelogram lattice ω₁=(4,0) ω₂=(-1,4);
     16 vertices, 32 triangles, χ=0 (genus 1).
   - Full pipeline: newton_euclidean → cut_graph → euclidean_layout
     → compute_period_matrix(reduce=false) + compute_period_matrix(reduce=true)
   - Asserts: raw Re(τ) < 0, normalized Re(τ) ∈ [0,½], Im(τ) > 0, |τ| ≥ 1

2. SyntheticHolonomy_NegativeReTau_NormalizedToPositive
   - Bypasses mesh; supplies explicit ω₁=(4,0) ω₂=(-1,4) directly
   - Asserts raw τ = -0.25+i (to 1e-10), normalized τ = 0.25+i (to 1e-9)
   - Pin-points the mirror fold: Re(-0.25) → Re(+0.25)

277/277 CGAL tests pass, 0 failed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 01:17:27 +02:00
Tarik Moussa
adbf682f0f test: add degenerate-triangle limiting-angle and edge-DOF guard tests
Finding-F and Finding-G from doc/reviewer/external-audit-2026-05-30.md
(java-port-audit missing-test items 1 and 2).

Finding-F — Degenerate triangle: limiting angles (item 1)
  test_euclidean_functional.cpp:
    DegenerateTriangle_LimitingAngles_L{12,23,31}TooLong
      — verifies α_opposite = π, other two = 0, valid = false
      for all three edge-over-long cases
    DegenerateTriangle_GradientPicksUpPiCorner
      — end-to-end mesh test: forces effective l12 >> l23+l31 via
        lambda0, evaluates gradient, asserts G_v3 = π (not 2π from
        a skipped degenerate face) and G_v1=G_v2 = 2π

  test_spherical_functional.cpp:
    DegenerateTriangle_LimitingAngles_S{12,23,31}TooLong
      — same coverage for spherical_angles()

Finding-G — euclidean_hessian edge-DOF guard (item 2)
  test_euclidean_hessian.cpp:
    EdgeDOFGuard_Throws
      — assign_euclidean_all_dof_indices + euclidean_hessian → throw
    EdgeDOFGuard_VertexOnlyDoesNotThrow
      — vertex-only layout → no throw (regression guard)

275/275 CGAL tests pass, 0 failed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 01:17:27 +02:00
Tarik Moussa
7534c62c3d fix(gradient-checks): use relative error in all FD check functions
Finding-E from doc/reviewer/external-audit-2026-05-30.md.
Scan also uncovered the same issue in inversive_distance_functional.hpp.

Three functions used absolute error `|analytic - fd| > tol` while the
rest of the library (euclidean_functional, spherical_functional,
euclidean_hessian, hyper_ideal_functional) all use relative error
`|analytic - fd| / max(1, |analytic|) > tol`.

Absolute error is too strict for large gradients (false failures) and
too lenient for small gradients.

Fixed:
  cp_euclidean_functional.hpp  gradient_check_cp_euclidean()
  cp_euclidean_functional.hpp  hessian_check_cp_euclidean()
  inversive_distance_functional.hpp  gradient_check_inversive_distance()

All three now use the relative criterion and accumulate all failures
before returning (ok=false instead of early return on first mismatch).
Default tol updated from 1e-6/1e-5 to 1e-4, matching the Java
FunctionalTest convention used by all other checks in the library.
Error message updated to print rel-err instead of raw diff.

266/266 CGAL tests pass, 0 failed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 01:17:27 +02:00
Tarik Moussa
cfbbc1b21f fix(dof-assign): correct "pin before" docs + add gauge-vertex overloads
Finding-D from doc/reviewer/external-audit-2026-05-30.md.

All three DOF-assignment functions iterated over every vertex
unconditionally, overwriting any v_idx set before the call.  The
documentation said "pin before OR after" — the "before" option was
silently wrong (the pin would be overwritten).  For the
inversive-distance variant the doc explicitly said the pre-call pin
would make the function "a no-op for that vertex", which was false.

Changes (three headers):
- euclidean_functional.hpp  assign_euclidean_vertex_dof_indices()
- spherical_functional.hpp  assign_vertex_dof_indices()
- inversive_distance_functional.hpp  assign_inversive_distance_vertex_dof_indices()

For each:
  1. Single-arg overload: doc corrected to "pin AFTER, not before;
     pre-call pins are overwritten"
  2. New two-arg overload accepting a Vertex_index gauge: pins the
     requested vertex (v_idx=-1) in a single pass, preventing the
     user error entirely

Three new GTests in test_euclidean_functional.cpp:
  SingleArg_PinBeforeHasNoEffect        — documents the old pitfall
  TwoArg_GaugeIsPinnedOthersAreSequential — verifies the new overload
  TwoArg_NewtonConvergesWithGaugeOverload — end-to-end correctness

266/266 CGAL tests pass, 0 failed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 01:17:27 +02:00
Tarik Moussa
bef5a0ceb7 docs(euclidean-hessian): fix wrong cotangent formula in two comment blocks
Finding-C from doc/reviewer/external-audit-2026-05-30.md.

The box comment at the top and the function-level comment above
euclidean_cot_weights() both stated:

  cot_k = (t_adj1·l123 − t_adj2·t_opp) / denom2   ← WRONG

The correct formula (verified numerically on a 3-4-5 right triangle,
expected cot1=4/3, cot2=3/4, cot3=0) is:

  cot_k = (t_opp · l123 − t_a · t_b) / denom2

where t_opp is the t-value of the edge OPPOSITE vertex k, and t_a/t_b
are the t-values of the two edges ADJACENT to vertex k.

The implementation in euclidean_cot_weights() was already correct;
only the documentation was wrong.

Changes (documentation only, zero code changes):
- Box comment: rewritten with correct formula and explicit per-vertex
  assignment (cot1: t_opp=t23, t_a=t12, t_b=t31; etc.)
- Box comment: added missing ½ factor to Hessian contribution lines
- Function-level comment: corrected to (t_opp·l123 − t_a·t_b)/(8·Area)
  with a pointer to the box comment for the full assignment
- Inline return comment in euclidean_cot_weights(): now shows the
  mapping (cot1: t_opp=t23, t_a=t12, t_b=t31) directly at the formula

263/263 CGAL tests pass, 0 failed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 01:17:27 +02:00
Tarik Moussa
46c0b63de8 fix(gauss-bonnet): delete HyperIdeal overloads — wrong identity for hyperbolic metrics
Finding-B from doc/reviewer/external-audit-2026-05-30.md.

The Euclidean Gauss–Bonnet identity Σ(2π−Θ_v) = 2π·χ is ONLY valid for
flat/Euclidean and spherical metrics.  For hyperbolic metrics (HyperIdeal)
the correct identity is Σ(2π−Θ_v) − Area(M) = 2π·χ.  The previously
provided gauss_bonnet_sum(HyperIdealMaps) overload would silently pass the
wrong LHS to check_gauss_bonnet, which would always throw "deficit = ±Area"
for valid hyperbolic targets.

Fix:
- gauss_bonnet_sum(mesh, HyperIdealMaps)        → = delete + explanation comment
- enforce_gauss_bonnet(mesh, HyperIdealMaps&)   → = delete + explanation comment
- Header box comment rewritten with the correct hyperbolic Gauss–Bonnet
  identity and a clear "HyperIdeal: NOT SUPPORTED" section

New test in test_phase6.cpp:
- HyperIdeal_EuclideanSumDiscrepancy_DocumentsWhyCheckIsDeleted
  verifies numerically that the Euclidean sum = 0 but 2π·χ = 4π for a
  regular tetrahedron, documenting the −4π discrepancy that motivated
  the deletion
- Three compile-time static_asserts (SFINAE) confirm the overload is not
  invocable with HyperIdealMaps but remains so with Euclidean/SphericalMaps

263/263 CGAL tests pass, 0 failed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 01:17:27 +02:00
Tarik Moussa
faf96ee28c doc(roadmap): add research item for 2/3-ideal hyper-ideal volume formulas
Follow-up to the Finding-A fix (face_energy guard).  The throw is the
correct safe behaviour for now; the mathematically complete solution
requires formulas for semi-ideal and fully-ideal tetrahedra that are
absent from the Java reference.

Adds a structured research entry to research-track.md (Phase 9b+):
- primary references: Kolpakov-Mednykh arXiv:math/0603097, Milnor 1982,
  Vinberg 1985
- acceptance criteria: two new volume functions + gradient-check tests +
  limiting-behaviour continuity witness
- explicit note that the throw in face_energy() must not be removed
  without implementing and testing the replacement formulas

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 01:17:27 +02:00
Tarik Moussa
9afefcbb7b fix(hyper-ideal): guard face_energy() against unsupported multi-ideal faces
Finding-A from doc/reviewer/external-audit-2026-05-30.md.

Root cause: both the Java reference (HyperIdealFunctional.java:222-231)
and the C++ port silently applied the one-ideal-vertex volume formula
to the first ideal vertex found in a face, ignoring any additional ideal
vertices.  For two or three ideal vertices this produces a wrong energy
value with no diagnostic.

Fix: add an ideal_count guard at the top of face_energy() that throws
std::logic_error for ideal_count >= 2.  The one-ideal (Kolpakov-Mednykh)
and zero-ideal (Meyerhoff/Ushijima) paths are unchanged and correct.

Three new GTests cover the three guard cases:
  MultiIdealGuard_TwoIdealVertices_Throws        (two ideal  → throw)
  MultiIdealGuard_AllThreeIdealVertices_Throws   (all ideal  → throw)
  MultiIdealGuard_ExactlyOneIdeal_DoesNotThrow   (one ideal  → no throw)

262/262 CGAL tests pass, 0 failed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 01:17:27 +02:00
Tarik Moussa
7f1a077269 doc(reviewer): add external audit 2026-05-30
Full external code review of v0.10.0 against all math-critical headers
(direct source read, not automated scan). Documents 5 open bugs/API errors,
3 test gaps inherited from java-port-audit.md, 1 architectural CI risk,
and 5 minor findings. Each finding is self-contained with file+line
references, a concrete fix proposal, and acceptance criteria so a new
session can pick up any single finding without prior context.

Key findings:
- FINDING-A (critical): face_energy() wrong for mixed ideal/hyper-ideal configs
- FINDING-B (medium):   Gauss–Bonnet API conceptually wrong for HyperIdeal
- FINDING-C (medium):   cotangent formula in euclidean_hessian.hpp header is wrong
- FINDING-D (medium):   DOF-assignment doc falsely claims "pin before" works
- FINDING-E (medium):   cp_euclidean gradient_check uses absolute not relative error
- FINDING-F/G/H:        three open test gaps from java-port-audit.md
- FINDING-I (arch):     246/272 CGAL tests not gated in CI

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 01:17:27 +02:00
Tarik Moussa
8619043b79 docs(crossvalidation): fix stale test count 243→259 after PRs #29-31 merged
Some checks failed
C++ Tests / test-fast (pull_request) Successful in 2m17s
API Docs / doc-build (pull_request) Successful in 1m1s
Markdown link check / check (pull_request) Successful in 43s
C++ Tests / test-cgal (pull_request) Has been skipped
C++ Tests / quality-gates (pull_request) Failing after 1m52s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 17:36:51 +02:00
Tarik Moussa
c472748e46 docs(reviewer): refresh §4 to mark Tier-1/3 done (stale TODO removed)
Some checks failed
C++ Tests / test-fast (pull_request) Successful in 2m1s
API Docs / doc-build (pull_request) Successful in 53s
Markdown link check / check (pull_request) Successful in 58s
C++ Tests / test-cgal (pull_request) Has been skipped
C++ Tests / quality-gates (pull_request) Failing after 2m14s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 17:32:02 +02:00
Tarik Moussa
082649ef40 docs(reviewer): mark Tier-3 done (PR #30); fix duplicated tier table
- Tier-3 (Lawson HyperIdeal) plain + branch-points marked DONE (PR #30,
  test_lawson_hyperideal.cpp); status, §3 HIGH/MED rows, §3b table and §4
  recommended-order updated accordingly.
- Hyperelliptic variant documented as deferred (option c): needs an XML-format
  reader for lawson_curve_source.xml + a port of HyperIdealHyperellipticUtility
  (jReality geometry θ); golden vector is non-symmetric.
- Removed a pre-existing duplicated/stale copy of the tier-table rows.
- Added a status summary (Tier 1  PR #29 · Tier 2 → Phase 9f/13 · Tier 3  PR #30).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 17:32:02 +02:00
Tarik Moussa
267ae965ab docs(reviewer): Tier-2 exhausted (genus≥2 → Phase 13); Tier-3 Lawson scoped as mini-project
- regular_uniformization.xml / LetterB01_canonical_group.xml are genus≥2
  hyperbolic Fuchsian-group uniformizations (12-edge fundamental polygon), not
  genus-1 → Phase 13, not Tier 2.
- Tier-2 is therefore exhausted (only Wente, deferred to Phase 9f quad/cyclic).
- Tier-3 Lawson HyperIdeal golden vectors require a low-level halfedge genus-2
  multi-edge generator (4 verts/12 edges) + jtem Triangulator replication;
  scoped as a dedicated follow-up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 17:32:02 +02:00
Tarik Moussa
822a27da69 feat(euclidean): full analytic edge-DOF (cyclic) Hessian; Tier-2 Wente finding
Upgrades the cyclic Euclidean Hessian from block-FD to closed-form, satisfying
the novelty-statement §3.2 "analytic Hessians, not finite difference" claim for
the Euclidean path.

- euclidean_hessian.hpp: `euclidean_hessian_analytic` — closed-form cyclic
  Hessian from the law-of-cosines angle derivatives
    ∂α_i/∂s_i = ℓ_i²/4A,  ∂α_i/∂s_j = ½cot α_i − ℓ_j²/4A   (Σ_j = 0),
  chained to (u, λ_e) and sign-mapped to the gradient outputs (−α vertex,
  +α_opp edge). Reuses euclidean_cot_weights. Block-FD kept as cross-check.
- newton_solver.hpp: newton_euclidean cyclic path now uses the analytic Hessian.
- tests: CyclicHessian_Analytic_MatchesBlockFD_Tetrahedron — analytic == block-FD
  (1e-6), == gradient FD (1e-5), symmetric (1e-9). Existing cyclic convergence
  oracle still GREEN with the analytic Hessian routed in.

Tier-2 (Wente) finding: wente_torus02.obj is a QUAD mesh (1240 quads) and the
Java golden comes from cyclic (quad-net) uniformization; the C++ period-matrix
pipeline is triangle-based, so a faithful bit-vs-Java τ comparison needs a
quad/cyclic pipeline (Phase 9f). Deferred and documented; golden τ = ½+i√3/2.

244/244 cgal tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 17:32:02 +02:00
Tarik Moussa
ea5f01d73d feat(euclidean): block-FD edge-DOF Hessian → cyclic Newton + Java convergence oracle
Implements the edge-DOF (cyclic) Euclidean Hessian, unblocking the full cyclic
Newton solve, and enables the Java EuclideanCyclicConvergenceTest cross-validation.

- euclidean_hessian.hpp: `euclidean_hessian_block_fd` / `_sym` — per-face 6×6
  block FD over (u1,u2,u3,λ12,λ23,λ31), mirroring hyper_ideal_hessian_block_fd.
  Per-face outputs carry the gradient signs (−α vertex, +α_opp edge), so the
  result equals ∂G/∂x by construction (locality lemma). Analytic vertex-only
  cotangent Hessian unchanged (still used for vertex-only layouts).
- newton_solver.hpp: newton_euclidean routes cyclic layouts (edge DOFs present)
  through the block-FD Hessian; vertex-only path unchanged.
- tests:
  * CyclicCircularEdge_CatHead_JavaXVal (now GREEN) — prescribe φ=π−0.1 on one
    interior edge, solve, assert realised α_opp+α_opp = π−0.1 @1e-9.
  * CyclicCircularEdge_PhiEntersGradient_CatHead — solver-free φ-wiring check.
  * CyclicHessian_BlockFD_MatchesGradientFD_Tetrahedron — Hessian correctness.

243/243 cgal tests pass; vertex-only Euclidean Newton unaffected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 17:32:02 +02:00
Tarik Moussa
5d74a94b78 test(euclidean): Tier-1 circular-edge φ cross-validation + cyclic-solve blocker
Build-verified attempt to port the Java EuclideanCyclicConvergenceTest
(cathead, "circular hole edge" φ = π−0.1).

-  GREEN `CyclicCircularEdge_PhiEntersGradient_CatHead`: solver-free
  cross-validation that the circular-edge φ target enters the cyclic edge
  gradient exactly (ΔG_e = −Δφ_e at 1e-12; no other component moves).
- ⏸️ DISABLED `CyclicCircularEdge_CatHead_JavaXVal`: the full Java convergence
  assertion (α_opp+α_opp = π−0.1), kept with golden semantics. Auto-activates
  once the edge-DOF Hessian lands.

Build-verification finding: `newton_euclidean` -> `euclidean_hessian` throws
"edge DOFs are not supported" — the cyclic full solve is blocked by a missing
edge-DOF Euclidean Hessian (gradient supports edge DOFs, analytic Hessian does
not). Spherical convergence (Tier-1 #2) is already covered by test_newton_solver.
Documented in doc/reviewer/java-ignore-crossvalidation.md.

All 13 EuclideanFunctional tests pass (1 disabled).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 17:32:02 +02:00
Tarik Moussa
41ad4a84d2 docs(reviewer): cross-validation analysis of Java @Ignore tests
Classifies the 22 Java @Ignore'd test files by root cause (ARM64 PETSc
native lib vs logic/known-issue) and by cross-validation value for the
C++ port.

- Notes what PR #27 already locks (math cores + functional-eval oracles)
  to avoid duplication.
- Priority ranking: HIGH (HyperIdeal Lawson convergence golden vector —
  records the exact u*), MEDIUM (genus-1 Wente uniformization, branch-point
  variant), LATER (genus-2/hyperelliptic/Mobius/quasi-isothermic/Schottky),
  NON-ORACLE (Java gaps: testHessian, testDoLayout; ARM64-flaky known issues).
- Documents why the Lawson mesh needs a low-level half-edge generator
  (4 vertices / 12 edges => multi-edges; CGAL add_face cannot build it).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 17:28:54 +02:00
adfcb7b931 Merge pull request 'feat(geometry): pn_geometry.hpp — Pn projective-metric substrate (jReality port)' (#31) from feat/pn-geometry-substrate into main
Some checks failed
C++ Tests / test-fast (push) Successful in 2m21s
API Docs / doc-build (push) Has been skipped
Markdown link check / check (push) Successful in 54s
Mirror to Codeberg / mirror (push) Successful in 43s
C++ Tests / test-cgal (push) Has been skipped
C++ Tests / quality-gates (push) Has been cancelled
2026-05-30 15:26:23 +00:00
Tarik Moussa
330515ea90 docs(java-parity): P2/Matrix jReality notes + Phase 9c dependency warning
All checks were successful
C++ Tests / test-fast (pull_request) Successful in 2m20s
API Docs / doc-build (pull_request) Successful in 52s
Markdown link check / check (pull_request) Successful in 1m1s
C++ Tests / test-cgal (pull_request) Has been skipped
C++ Tests / quality-gates (pull_request) Successful in 2m24s
- Infrastructure table: add Matrix (→ Eigen inline, done) and P2 rows.
  P2 marked "port inline with Phase 9c" — almost exclusively consumed by
  FundamentalPolygon/CanonicalForm/SurfaceCurve (all Phase 9c), so building
  p2_geometry.hpp as a standalone ahead of 9c would be dead weight.
- Phase 9c rows in the utility table: ⚠️ annotation listing the exact P2.*
  methods needed (makeDirectIsometryFromFrames, projectP3ToP2,
  imbedMatrixP2InP3) plus the P2Big/cpp_dec_float_50 high-precision
  prerequisite for the group-relation product ∏gᵢ = Id.

Ensures a future Phase 9c session starts with full context and does not
discover the jReality/precision dependencies mid-port.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 17:20:35 +02:00
Tarik Moussa
149da15c64 feat(geometry): pn_geometry.hpp — Pn projective-metric substrate (jReality port)
Ports the small but pervasive de.jreality.math.Pn surface that the Java
algorithmic core uses across every not-yet-ported geometric phase:
HyperbolicLayout, SphericalLayout, FundamentalPolygon (9c), KoebePolyhedron
(10c'), quasi-isothermic (10e), hyperelliptic theta, CircleDomain (11c).
Porting it once unblocks all downstream consumers instead of re-deriving
the metric ad hoc per phase.

pn_geometry.hpp — header-only, Eigen, ~120 LOC:
  PnMetric { EUCLIDEAN=0, ELLIPTIC=+1, HYPERBOLIC=-1 } matching jReality.
  pn_inner_product  — bilinear form per signature.
  pn_norm / pn_dehomogenize / pn_set_to_length / pn_normalize.
  pn_distance_between — Euclidean (spatial), elliptic (acos), hyperbolic (acosh).
  pn_linear_interpolation — affine (E) and slerp (S/H constant-speed geodesic).

HYPERBOLIC uses the timelike-positive ("upper-sheet") convention, identical to
the already-verified projective_math.hpp::hyperbolicDistance; pn_distance_between
is regression-anchored against it in the tests.

test_pn_geometry.cpp — 6 tests, all GREEN:
  InnerProductSignatures, EuclideanDistance, EllipticDistanceIsAngle,
  HyperbolicDistanceClosedFormAndAnchor (+ projective_math.hpp anchor),
  NormAndScaling, LinearInterpolationGeodesic.

doc/roadmap/java-parity.md — new "Infrastructure / support layers" section:
  de.jreality.math.Pn   → pn_geometry.hpp (partial, 6 fns covering core usage)
  de.jreality.math.Rn   → Eigen (no separate port needed)
  MatrixBuilder         → not yet (only needed for hyperelliptic theta)
  conformallab XML types → not planned (GUI persistence, not algorithmic)

246/246 cgal tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 17:20:35 +02:00
a993a101e9 Merge pull request 'docs: citation audit (8 mis-citations fixed) + Phases 12/13' (#28) from docs/citation-audit-phases-12-13 into main
Some checks failed
C++ Tests / test-fast (push) Successful in 2m15s
API Docs / doc-build (push) Has been skipped
Markdown link check / check (push) Successful in 47s
Mirror to Codeberg / mirror (push) Successful in 27s
C++ Tests / test-cgal (push) Has been skipped
C++ Tests / quality-gates (push) Failing after 1m51s
Reviewed-on: #28
2026-05-30 08:06:33 +00:00
Tarik Moussa
26f4f0637d docs: citation audit + correct 8 mis-citations; add Phases 12/13
Some checks failed
C++ Tests / test-fast (pull_request) Successful in 1m55s
API Docs / doc-build (pull_request) Successful in 53s
Markdown link check / check (pull_request) Successful in 50s
C++ Tests / test-cgal (pull_request) Has been skipped
C++ Tests / quality-gates (pull_request) Failing after 1m56s
External reviewer pass over the literature references. Verified entries
against arXiv/DOI/publisher and corrected misattributions that had
propagated across the docs.

Corrected citations (consistent across all docs):
- Bowers-Bowers-Lutz 2026: title was the 2017 paper's
  -> "Rigidity of Koebe Polyhedra and Inversive Distance Circle Packings"
- Liouville theorem: "Springborn 2019" -> Pinkall & Springborn,
  Geom. Dedicata 214 (2021)
- Bobenko-Pinkall-Springborn: "G&T 14 (2010)" -> G&T 19(4) (2015), 2155-2215
- Optimal Cone Singularities: "Crane, Soliman, Ben-Chen, Schroeder"
  -> Soliman, Slepcev, Crane, ACM TOG 37(4)
- Schlaefli formula: "Rivin, Springborn 1999" -> Rivin, Schlenker
- Quasiconformal distortion: "Springborn, Veselov" -> Born, Buecking,
  Springborn (arXiv:1505.01341)
- Period matrices: "Bobenko, Buecking 2009" (was Bobenko-Mercat-Schmies'
  title) -> Bobenko-Mercat-Schmies 2011 + genuine Bobenko-Buecking 2021
- Fabricated entry: "Alexa 2020, DOI 10.1145/3414685.3417840" pointed to
  an unrelated paper (Pixelor) -> Bunge, Herholz, Kazhdan, Botsch 2020
- Stripe Patterns: "Bonneel et al. 2015" -> Knoeppel, Crane, Pinkall,
  Schroeder 2015

Equation-number corrections (verified against the PDFs):
- Glickenstein 2011 "eq. 4.6" -> "§5.2" (no such equation label exists)
- Springborn 2020 "eq. 4.6" -> "§4 variational gradient"
- inversive-distance attribution softened to classical inversive distance

Other:
- DBFEnergy bibliography (separate repo) and convergence half-sentence in
  novelty-statement.md §3.3 (Bobenko-Buecking 2021)
- Status legend (implemented vs planned) at top of references.md
- New Phase 12 (decorated DCE & geometric transition, Chain A, near-term)
  and Phase 13 (canonical tessellations & polyhedral realisation, Chain B
  capstone) in phases.md + research-track.md; 10c scope-boundary note
  clarifying infrastructure vs Lutz-specific algorithms

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 19:17:17 +02:00
Tarik Moussa
ba83974525 test: Java golden-value oracles for the five DCE math cores + P1-2/P1-3 fixes
All checks were successful
C++ Tests / test-fast (pull_request) Successful in 1m57s
API Docs / doc-build (pull_request) Successful in 59s
Markdown link check / check (pull_request) Successful in 51s
C++ Tests / test-cgal (pull_request) Has been skipped
C++ Tests / quality-gates (pull_request) Successful in 2m19s
Add bit-for-bit (1e-12) golden-value oracle tests pinning the C++ pure-math
and functional cores against the compiled upstream Java library (openjdk 17):

- HyperIdealGoldenJava: Clausen/Л/ImLi2, ζ13/14/15/ζ, both tetrahedron-volume
  formulas (real de.varylab…Clausen / HyperIdealUtility).
- EuclideanGoldenJava / SphericalGoldenJava: angle formulas + β relations + Л
  energy terms, plus FULL-MESH oracles driving the real EuclideanCyclicFunctional
  / SphericalFunctional on a shared tetrahedron — per-vertex gradient (Θ−Σα) and
  ΔE = E(x)−E(0) (C++ Gauss-Legendre path integral vs Java closed form).
- SphericalGoldenJava.FullMeshEdgeDofGradient: edge-DOF gradient (vertex + edge
  components, α_opp⁺+α_opp⁻−θ_e) vs raw conformalEnergyAndGradient — locks
  Finding 3 at the solution level (audit items 4 & 5).
- PeriodMatrix.NormalizeModulus_GoldenJava: τ-reduction fold convention vs the
  real DiscreteEllipticUtility.normalizeModulus (audit items 7 & 8).

Subtlety documented: the spherical oracles call Java's raw
conformalEnergyAndGradient, not evaluate() (which pre-runs a Brent gauge
maximization that C++ factors into the Newton solver's spherical_gauge_shift).

Also:
- P1-2 (layout.hpp): Euclidean holonomy now uses a per-cut-edge rigid-motion fit
  g(z)=a·z+b, exposing residual_rotation = |arg(a)| as a diagnostic; non-
  regressive (flat case a=1 reduces to the old midpoint formula).
- P1-3 (period_matrix.hpp): is_in_fundamental_domain fixed to the correct
  half-open SL(2,ℤ) domain (−½ ≤ Re < ½). Updated the now-exposed
  ComputePeriodMatrix_ReducedTau_InFD to assert the normalizeModulus domain
  (closed +½ edge) instead.

Test counts (single source of truth = doc/api/tests.md): 272/272 pass, 0
skipped (26 non-CGAL + 246 CGAL).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 19:08:37 +02:00
Tarik Moussa
a3ee9576d4 fix+test: Euclidean holonomy/τ end-to-end + spherical edge-DOF oracle (2026-05-29 audit)
All checks were successful
C++ Tests / test-fast (pull_request) Successful in 1m57s
API Docs / doc-build (pull_request) Successful in 1m3s
Markdown link check / check (pull_request) Successful in 44s
C++ Tests / test-cgal (pull_request) Has been skipped
C++ Tests / quality-gates (pull_request) Successful in 2m11s
Bundles the 2026-05-29 Java↔C++ math-correctness audit (doc/reviewer/
java-port-audit.md, 11 findings) with two follow-up fixes.

Audit code changes:
- Finding 3 (spherical_functional): edge-DOF replacement parameterization via
  spher_eff_lambda; edge gradient α_opp⁺+α_opp⁻−θ_e (drops additive −(S⁺+S⁻)/2)
- Finding 4 (spherical_hessian): always-compiled edge-DOF throw guard
- Finding 6 (period_matrix): faithful normalizeModulus (0≤Re≤½, Im≥0, |τ|≥1)
- Finding 9 (inversive_distance): degenerate-face limiting angles, no skip
- Findings 1/2 (euclidean): degenerate gradient limiting angles + Hessian guard

Euclidean holonomy/τ fix: develop the cut surface across the dual spanning tree
only (cut_graph now exposes is_dual_tree), so genus-1 cut edges yield
non-degenerate lattice generators. Previously τ came out 0 / NaN / 1e13 on the
bundled tori; now matches the analytic revolution modulus i·√(R²−r²)/r. Re-enabled
τ reporting in the Euclidean CLI; rewrote validation.md §3/§4 accordingly.

Tests (240 CGAL, 0 skipped):
- HolonomyEndToEnd ×3 — tori of revolution (4×4, hex 6×6, 8×8) vs analytic modulus
- SphericalFunctional.EdgeGradient_RegularTetClosedForm — independent closed-form
  π/3 oracle locking the Finding-3 edge formula (the path-integral FD check cannot
  detect a wrong-but-conservative gradient)

Also documents the latent spherical/hyperbolic holonomy-extraction bug (same
single-development pattern, dead code today) in research-track.md (Phase 9c/10),
and adds favour/normalisations to the codespell ignore list.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 12:50:16 +02:00
Tarik Moussa
ca936b7652 docs: note high-precision requirement for Phase 9c/10 uniformization
Some checks failed
C++ Tests / test-fast (pull_request) Successful in 2m0s
API Docs / doc-build (pull_request) Successful in 53s
Markdown link check / check (pull_request) Successful in 54s
C++ Tests / test-cgal (pull_request) Has been skipped
C++ Tests / quality-gates (pull_request) Failing after 2m14s
The Java uniformization classes (FundamentalPolygonUtility, CanonicalFormUtility)
rely on the *Big arbitrary-precision geometry (MathContext(50)) because products
of hyperbolic isometry generators grow exponentially and double fails to verify
the group relation ∏gᵢ = Id. Record this planning-relevant prerequisite and
resolve the contradiction in java-parity.md, which previously listed *Big as
permanently out of scope.

- CLAUDE.md: † note on the Phase-9 not-yet-ported table
- java-parity.md: *Big exception (localized high-precision substrate for 9c/10)
- phases.md: precision prerequisite as 9c sub-task + effort estimate
- design-decisions.md: new "Scalar type: double, with one localized exception"

Core flattening (Newton/energy/Eigen solver) stays double; the substrate
(cpp_dec_float_50 / mpreal) is localized to the uniformization module only.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 07:41:23 +02:00
Tarik Moussa
1ff5382c8b docs: record 2026-05-28 full-library scan findings in roadmap
Some checks failed
C++ Tests / test-fast (pull_request) Successful in 1m55s
API Docs / doc-build (pull_request) Successful in 53s
Markdown link check / check (pull_request) Successful in 1m1s
C++ Tests / test-cgal (pull_request) Has been skipped
C++ Tests / quality-gates (pull_request) Failing after 2m3s
Cross-referenced all 232 Java classes against the roadmap. New plan
entries for genuinely-useful, previously-unplanned items:
- 9g.1 conformal quality measures (Isothermicity, ConformalEquivalence,
  FlippedTriangles, LengthCrossRatio + ConvergenceUtility metrics)
- 9g.2 optional period-matrix convergence experiment (method only;
  Java harness depends on Mathematica/JLink + jReality, not ported)
- DEC operator layer (heds/dec/) noted as a 10a prerequisite
- HomotopyUtility -> 10a (explicit generator cycles; not covered by
  cut_graph.hpp, which yields only the 2g cut edges)
- SurfaceCurveUtility -> 9c; MercatorTextureProjection -> 9d.3 companion

Documented as deliberately out-of-scope: SpanningTreeUtility (subsumed
by cut_graph.hpp), convergence/* harness, datasource/* (jReality viewer
decoration), *Big arbitrary-precision geometry, jReality GUI, and the
MTJ/Tao/PETSc solver bindings.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 06:53:09 +02:00
Tarik Moussa
569a03dc08 docs+tooling: doc-freshness gate, documentation-pass policy, token-hygiene
All checks were successful
C++ Tests / test-fast (pull_request) Successful in 2m2s
API Docs / doc-build (pull_request) Successful in 1m8s
Markdown link check / check (pull_request) Successful in 52s
C++ Tests / test-cgal (pull_request) Has been skipped
C++ Tests / quality-gates (pull_request) Successful in 1m59s
Refresh CLAUDE.md for v0.10.0 (3 CI jobs incl. disabled test-cgal,
compile-time option matrix, reviewer/pages docs, agentic + token-hygiene
workflow patterns) and condense the historical Phase-8/audit logs to
pointers.

Add the documentation-pass process so the single-source-of-truth rules
stay enforced:
  * scripts/quality/check-doc-freshness.sh — string-only drift gate
    (version/date across CITATION/CHANGELOG/CLAUDE, doc-map count), <1 s,
    registered in run-all.sh + quality README.
  * doc/release-policy.md — "Documentation passes" subsection (triggers +
    docs:sync rule); fix stale Phase-milestone mapping (v0.10.0 was
    reviewer-ready, 9c→v0.11.0) and the test-cgal CI mention.

Add shared Claude config (un-ignore the two files only):
  * .claude/settings.json — permission allowlist for safe repo commands.
  * .claude/token-hygiene.md — Tier-3 cache-discipline user guide that
    CLAUDE.md instructs Claude to remind the user about.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 06:15:14 +02:00
Tarik Moussa
11d660af49 fix(hub): correct double-branch/branch/main URL prefix + v0.10.0 badge
Some checks failed
C++ Tests / test-fast (pull_request) Successful in 2m20s
API Docs / doc-build (pull_request) Successful in 49s
C++ Tests / test-cgal (pull_request) Failing after 8m18s
C++ Tests / quality-gates (pull_request) Successful in 1m52s
Two bugs in the reviewer hub HTML:

1. The earlier sed-rewrite that lifted the hub from
   `preview/reviewer-snapshot-v6` into `branch/main` accidentally
   produced `branch/branch/main` — sed pattern matched the
   `preview/reviewer-snapshot-v6` slug but the surrounding URL
   already had `/src/branch/` prefix.  All 25 in-hub links to the
   repo were broken with 404 on codeberg.org.

   Fix: `s|/src/branch/branch/main/|/src/branch/main/|g`.

2. The version pill in the badge strip still read v0.9.0 (stale
   from the original v0.9.0-era hub template).  Updated to v0.10.0.

The fix is in this in-repo source-of-truth file so any future manual
republication of the pages branch picks up the corrected hub.  The
just-pushed pages branch already has the fix applied; codeberg's
`tmoussa.codeberg.page` frontend cache (max-age=600 s) will refresh
over the next 10 minutes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 11:50:59 +02:00
Tarik Moussa
09a68a4569 release: v0.10.0 — reviewer-ready release
Some checks failed
C++ Tests / test-fast (pull_request) Successful in 2m16s
API Docs / doc-build (pull_request) Successful in 49s
Markdown link check / check (pull_request) Successful in 51s
C++ Tests / test-cgal (pull_request) Failing after 7m34s
C++ Tests / quality-gates (pull_request) Successful in 2m20s
Post-merge consistency commit:

  * CITATION.cff version 0.9.0 → 0.10.0, date 2026-05-26
  * CHANGELOG.md — new "[0.10.0]" section listing all 13 commits
    that landed across PRs #17 / #18 / #19
  * Post-merge gate fixes:
      - doxygen_groups.h + doxygen_namespaces.h gain \\file briefs
      - .codespellrc extended (honour, thead, optimiser)
      - compile-time.md: unbalanced backtick on line 102 fixed
        (was confusing Doxygen's verbatim-block detector)

Final gate state on the merged main:
   259/259 tests pass
   test-count consistency
   markdown links 166/166 resolve (43 .md files)
   CGAL conventions 0/8 violations
   license-headers 68/68 carry MIT SPDX
   codespell 0 typos
   shellcheck 0 findings (18 scripts)
   Doxygen 396/396 symbols, 0 warnings

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 11:24:16 +02:00