# CGAL Submission-Readiness Audit โ€” ConformalLabpp **Date:** 2026-05-31 **Auditor:** External reviewer (Claude Opus 4.8) **Scope:** Readiness of the `code/include/CGAL/` package for submission to the CGAL project (editorial-board review + integration into the CGAL release). **Reference:** CGAL Developer Manual โ€” "Adding a new package", CGAL coding conventions, and the CGAL package directory structure. This document is self-contained. A new session can pick up any finding below and act on it without prior context. Status legend: โ›” Blocker (submission rejected on sight) ยท ๐Ÿ”ด Critical ยท ๐ŸŸก Important ยท ๐Ÿ”ต Polish > **๐Ÿ”„ Status (2026-05-31):** the whole package โ€” **G0** (porting rights), and > everything it gates (**G1โ€“G12**) โ€” is **blocked pending the original authors' > reply**. The authors have been **contacted by email** asking to clarify > porting/relicensing rights. No layout/license/header work proceeds until a > written answer exists. Scheduled as **S6** (Opus, after G0/G1) in > [`finding-orchestration.md`](finding-orchestration.md). > **Companion documents:** > - `external-audit-2026-05-30.md` โ€” port-faithfulness bugs > - `test-coverage-error-handling-audit-2026-05-31.md` โ€” test gaps + error handling > - `api-performance-audit-2026-05-31.md` โ€” API consistency + performance > - **this file** โ€” CGAL submission readiness > > **Bottom line:** the *algorithmic* maturity is strong, but the package is **not > submittable as-is**. There are **three** hard blockers โ€” **provenance/porting > rights (G0)**, licensing (G1), and directory layout (G2) โ€” plus several > CGAL-convention gaps. G0 is a legal precondition that gates everything else: > until the right to port the original Varylab/TU-Berlin code is clarified with > its authors, no license decision (G1) can be made and no public release or > submission should happen. The remaining items are packaging and > documentation-format work โ€” substantial but mechanical, no research required. --- ## Verdict at a glance | # | Sev | Title | |---|-----|-------| | G0 | โ›” | **Porting rights unclear** โ€” the original Varylab/TU-Berlin project has *no license* (all rights reserved); the C++ code is a documented *port* (derivative work). Must clarify with the authors whether porting + (re)licensing is permitted **before** any license/release decision | | G1 | โ›” | **License is MIT** โ€” CGAL requires GPLv3+ (algorithmic) or LGPLv3+. Moot until G0 is resolved | | G2 | โ›” | **Directory layout is not CGAL package layout** โ€” no `package_info/`, no `doc//`, tests/examples not in CGAL harness | | G3 | ๐Ÿ”ด | **CGAL is vendored** (`code/deps/CGAL-6.1.1`) โ€” a CGAL package must not bundle CGAL | | G4 | ๐Ÿ”ด | **Concept not in a Doxygen block** โ€” `\cgalConcept` is in `//` comments, won't render; no `doc//Concepts/` file | | G5 | ๐Ÿ”ด | **No user manual** โ€” CGAL requires `.txt` (\mainpage) + `PackageDescription.txt` | | G6 | ๐Ÿ”ด | **Test suite uses GoogleTest + FetchContent** โ€” CGAL uses its own test harness; external network deps are disallowed | | G7 | ๐ŸŸก | **Primary template `Default_conformal_map_traits` is undefined** โ€” only `Surface_mesh` works; concept claims `FaceGraph` genericity | | G8 | ๐ŸŸก | **`.hpp` extension for implementation headers** โ€” CGAL convention is `.h` | | G9 | ๐ŸŸก | **Single-header monolith risk** โ€” heavy `inline` free functions in headers; CGAL prefers `internal/` split + documented public surface | | G10 | ๐ŸŸก | **No demo, no benchmark dir** โ€” recommended for a numeric package | | G11 | ๐Ÿ”ต | **Naming inconsistencies** carry into the public API (see api-performance-audit A1โ€“A5) | | G12 | ๐Ÿ”ต | **Copyright line** โ€” CGAL files carry an `INRIA/GeometryFactory` style header + the CGAL license boilerplate, not a bare MIT line | --- ## G0 โ€” โ›” Porting rights: the original is unlicensed and this is a derivative work > **This is the precondition for everything else in this audit (and for the license > finding G1). It must be resolved with the original authors before any public > release, relicensing, or CGAL submission.** > > *Disclaimer: the auditor is not a lawyer. This is a practical risk assessment, > not legal advice. Confirm with the project owner / institutional legal counsel.* ### Evidence The original project (`gitlab.discretization.de:varylab/conformallab.git`, mirrored to `git.eulernest.eu`) is the **Varylab / TU-Berlin** discrete-conformal codebase (DFG SFB/Transregio "Discretization in Geometry and Dynamics"; author circle around Stefan Sechelmann, Boris Springborn). ``` $ find /Users/tarikmoussa/Desktop/conformallab -maxdepth 2 \ \( -iname 'license*' -o -iname 'copying*' \) # โ†’ (nothing) # Java sources carry NO license header; only build.xml + .project exist. ``` - The original has **no LICENSE file and no per-file license headers** โ†’ under default copyright law this means **all rights reserved** by the TU-Berlin/Varylab authors. "Publicly visible on an academic GitLab" is **not** a license grant. - `ConformalLabpp` describes itself as a **port**: source comments say *"Ported from de.varylab.discreteconformal.functional.EuclideanCyclicFunctional"*, and the test suite asserts "Java golden-oracle parity". That makes the C++ code a **derivative work of the original source code**, not merely an independent implementation of the published papers. ### Why it blocks A derivative work of all-rights-reserved code **cannot be licensed by the porter alone** โ€” neither as MIT (the current state) nor as GPL (the CGAL requirement) โ€” without permission from the original copyright holders. The existing MIT header on `ConformalLabpp` is therefore on shaky ground today, independent of CGAL. Crucial distinction: | What was actually reproduced | Legal status | |---|---| | The **published algorithms** (Springborn 2020, Bobenko-Pinkall-Springborn 2010, Luo 2004) | Free to reimplement โ€” mathematical methods are not copyrightable, only their concrete code expression | | The **source code** of the Varylab Java project, line-by-line | Derivative work โ†’ requires the authors' permission to port and (re)license | The "Ported from โ€ฆ" comments currently document a code derivation in writing, which is the principal risk. ### Action (owner-level, before any code/license change) 1. **Determine provenance honestly:** is `ConformalLabpp` a clean-room reimplementation *from the papers*, or a translation *of the Varylab code*? The current comments assert the latter. 2. **Contact the original authors** (Sechelmann / Springborn, TU Berlin / Varylab) to either (a) obtain written permission to port and relicense (ideally under GPLv3+ so CGAL submission stays open), or (b) confirm the original is intended to be freely reusable and get that in writing / as an added LICENSE upstream. 3. **Pause public releases and CGAL submission** until 1โ€“2 are settled. 4. If permission cannot be obtained, the only clean path is a genuine clean-room reimplementation from the published papers, with the "Ported from โ€ฆ" provenance comments removed and replaced by paper citations. ### Done when - Written clarity exists on the right to port + (re)license the original code; the provenance comments in the source match that reality. --- ## G1 โ€” โ›” License: MIT is incompatible with CGAL submission > Blocked by **G0** โ€” do not act on G1 until porting/relicensing rights are clear. ### Evidence All 41 headers carry: ```cpp // SPDX-License-Identifier: MIT ``` (`grep -rh "SPDX-License-Identifier" code/include/` โ†’ 41ร— MIT, 0ร— anything else.) ### Why it blocks CGAL is dual-licensed: the **algorithmic** packages are **GPLv3+**, the foundational ones **LGPLv3+**, with a commercial license sold by GeometryFactory. A new package must be contributed under the **same dual GPL/LGPL scheme**, with copyright assigned or licensed appropriately. A package licensed MIT cannot be merged into the CGAL tree โ€” the editorial board will reject it at intake. ### Action This is a **licensing/legal decision for the project owner**, not a code change: 1. Decide whether to relicense the contributed package as GPLv3+ (the normal choice for a new algorithmic CGAL package). 2. Replace every header's `SPDX-License-Identifier: MIT` with the CGAL license header boilerplate (see `Installation/LICENSE*` in the CGAL tree for the exact text and the `$URL$ $Id$ SPDX-License-Identifier: GPL-3.0-or-later` form). 3. Keep a separate MIT-licensed standalone build if a permissive standalone distribution is also desired (dual-distribution is possible but must be explicit). > โš ๏ธ Do not auto-rewrite license headers without the owner's explicit decision โ€” > relicensing is irreversible for contributed copies and may involve other authors. ### Done when - Owner has chosen the license; headers carry the CGAL-conformant boilerplate. --- ## G2 โ€” โ›” Directory layout is not a CGAL package ### Evidence Current layout: ``` code/include/CGAL/... โ† headers (good location) code/examples/*.cpp โ† flat, not per-package code/tests/cgal/*.cpp โ† GoogleTest, not CGAL harness code/deps/CGAL-6.1.1 โ† vendored CGAL (see G3) (no package_info/ anywhere) (no doc// with PackageDescription.txt) ``` CGAL expects a package rooted at a top-level package directory mirroring the CGAL source tree: ``` Discrete_conformal_map/ include/CGAL/Discrete_conformal_map.h include/CGAL/Conformal_map/... doc/Discrete_conformal_map/ Discrete_conformal_map.txt (user manual, \mainpage) PackageDescription.txt (\package_listing entries) Concepts/ConformalMapTraits.h (the concept, doxygen-only) examples.txt, fig/ examples/Discrete_conformal_map/*.cpp (+ CMakeLists using CGAL macros) test/Discrete_conformal_map/*.cpp (CGAL test harness) benchmark/Discrete_conformal_map/ (optional but recommended) package_info/Discrete_conformal_map/ copyright description.txt dependencies license.txt maintainer ``` ### Action Restructure into the CGAL package layout. This is mechanical but touches every file location and the build. Recommended approach: 1. Create the `package_info/Discrete_conformal_map/` metadata files first (small). 2. Move headers under the package's `include/CGAL/` (already close). 3. Re-home examples โ†’ `examples/Discrete_conformal_map/`, tests โ†’ `test/Discrete_conformal_map/`. 4. Build the `doc/Discrete_conformal_map/` tree (G5). ### Done when - Layout matches an existing CGAL package (use e.g. `Surface_mesh_parameterization` or `Heat_method_3` as a template โ€” both are close in spirit). --- ## G3 โ€” ๐Ÿ”ด CGAL is vendored inside the repo ### Evidence ``` code/deps/CGAL-6.1.1 โ† full CGAL 6.1.1 source tree bundled ``` ### Why it matters A package being submitted *into* CGAL must build against the surrounding CGAL tree, not bundle its own copy. The vendored `CGAL-6.1.1` (and the standalone build wiring around it) is appropriate for the current standalone distribution, but must be removed from the submitted package โ€” the package's `dependencies` file declares CGAL package dependencies instead. ### Action - For the CGAL-submission branch: drop `code/deps/CGAL-*`; rely on the host CGAL tree. - Keep the vendored copy only on the standalone-distribution branch. - List actual dependencies (`Surface_mesh`, `BGL`, `Property_map`, `Solver_interface`, `Number_types`, plus the external `Eigen`) in `package_info/.../dependencies`. ### Done when - The submission branch contains no bundled CGAL; it builds inside a CGAL checkout. --- ## G4 โ€” ๐Ÿ”ด The concept is not a documented CGAL concept ### Evidence `code/include/CGAL/Conformal_map_traits.h:36-76` declares the concept with `\cgalConcept`, `\concept ConformalMapTraits`, `\cgalHasModelsBegin/End` โ€” but the whole block uses **plain `//` comments**, not a Doxygen `/*! ... */` block: ```cpp // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• // \cgalConcept // // \concept ConformalMapTraits ... ``` Doxygen only parses `/*! */` (or `///`) blocks, so none of this renders. There is also no `doc//Concepts/ConformalMapTraits.h` โ€” in CGAL, concepts live as doxygen-only header files under the package `doc/.../Concepts/` directory, separate from the model. ### Action 1. Create `doc/Discrete_conformal_map/Concepts/ConformalMapTraits.h` containing the concept as a `/*! \cgalConcept ... */`-documented (empty) class, following the CGAL concept-file pattern. 2. Reference it via `\cgalHasModels` from `Default_conformal_map_traits`. 3. Convert the in-source `//` concept block to either a proper `/*! */` block or remove it in favor of the doc/Concepts file. ### Done when - `ConformalMapTraits` appears in the generated reference manual under `PkgConformalMapConcepts` with its model linked. --- ## G5 โ€” ๐Ÿ”ด No CGAL user manual / PackageDescription ### Evidence `find . -name PackageDescription.txt -o -path '*doc*' -name '*.txt'` โ†’ none (outside `deps/`). The project has rich Markdown docs under `doc/` (api/, math/, architecture/), but CGAL requires its own doxygen-driven manual files: - `doc//.txt` โ€” the user manual with `\mainpage`-style narrative, `\cgalExample` references, figures. - `doc//PackageDescription.txt` โ€” the `\cgalPkgDescriptionBegin` listing (authors, intro, license, dependencies, demo/example links) that populates the CGAL "Packages" overview. ### Action - Author `Discrete_conformal_map.txt` (user manual). Much of the content can be adapted from the existing `doc/api/pipeline.md` and `doc/math/*.md`. - Author `PackageDescription.txt` with the standard CGAL macros. - Wire both into a package `doc/Doxyfile.in` consistent with CGAL's doc build. ### Done when - `cgal_create_package` doc build produces a reference + user manual without warnings. --- ## G6 โ€” ๐Ÿ”ด Test suite is GoogleTest + FetchContent ### Evidence `code/tests/cgal/CMakeLists.txt`: ```cmake target_link_libraries(conformallab_cgal_tests PRIVATE GTest::gtest_main) gtest_discover_tests(conformallab_cgal_tests ...) ``` (plus FetchContent for GoogleTest elsewhere in the build). ### Why it matters CGAL's test infrastructure uses its own harness (`create_single_source_cgal_program`, the `test/` programs return 0/non-0, driven by the CGAL testsuite scripts). External network dependencies (FetchContent pulling GoogleTest) are not allowed in the CGAL tree, and the GoogleTest dependency would need vendoring or removal. ### Action This is the largest mechanical task. Options: - **(a)** Port the assertions to CGAL's plain-`assert` + `return EXIT_FAILURE` test style, one program per test file under `test/Discrete_conformal_map/`. This is the canonical CGAL approach and removes the GoogleTest dependency entirely. - **(b)** Keep GoogleTest for the standalone branch; maintain a parallel CGAL-style `test/` tree for the submission branch. The 272 existing tests are an asset โ€” the assertions translate directly; only the framework scaffolding changes. ### Done when - `test/Discrete_conformal_map/` runs under the CGAL testsuite with no GoogleTest. --- ## G7 โ€” ๐ŸŸก Genericity claimed but not delivered ### Evidence `Conformal_map_traits.h:80-92`: the primary template `Default_conformal_map_traits` is **declared but undefined**; only the `Surface_mesh` partial specialization (`:113`) is implemented. The concept docstring (`:13-21`) advertises *"can run on any CGAL halfedge mesh โ€” Surface_mesh, Polyhedron_3, OpenMesh-adapter, pmp โ€” without changes"*, and the API takes a `TriangleMesh` template parameter, implying BGL-generic support. ### Why it matters CGAL reviewers scrutinize generic-programming claims. Shipping a `TriangleMesh` template that compiles only for `Surface_mesh` is a documentation/implementation mismatch: a user passing a `Polyhedron_3` gets a hard template error against an undefined primary template, not a clean diagnostic. ### Action Either: - **(a)** Implement a generic `FaceGraph`/`HalfedgeGraph` path using `boost::graph_traits` + dynamic property maps (CGAL's `dynamic_vertex_property_t`), removing the `Surface_mesh`-only restriction โ€” this is the "Phase 8a.2" already on the roadmap; or - **(b)** Until then, narrow the documented contract: state explicitly that only `Surface_mesh` is supported, and `static_assert` a friendly message in the primary template instead of leaving it undefined. ### Done when - The advertised mesh-type support matches what compiles; unsupported types yield a `static_assert` message, not a raw template error. --- ## G8 โ€” ๐ŸŸก Header extension `.hpp` vs CGAL `.h` ### Evidence The implementation headers use `.hpp` (`euclidean_functional.hpp`, `newton_solver.hpp`, โ€ฆ), while the CGAL-facing headers correctly use `.h` (`Discrete_conformal_map.h`). CGAL's convention is `.h` for all headers. ### Action Rename the implementation headers to `.h` when they move under the package `include/CGAL/Conformal_map/internal/` tree (G9), updating `#include` directives. Low-risk, mechanical; do it as part of the G2 restructure. ### Done when - All package headers use `.h`. --- ## G9 โ€” ๐ŸŸก Public/internal header surface is undivided ### Evidence The 26 `code/include/*.hpp` headers are all effectively public (flat in `include/`), mixing the user-facing CGAL entry points with low-level functional/geometry/solver internals (`hyper_ideal_geometry.hpp`, `projective_math.hpp`, `clausen.hpp`, โ€ฆ). ### Why it matters CGAL packages keep a small documented public API and move implementation into `include/CGAL//internal/`. Exposing every helper as a top-level header makes the supported API surface ambiguous and the package harder to evolve without breaking users. ### Action - Designate the public surface (the `CGAL/Discrete_*` entry points, the traits, the layout/result types). - Move everything else under `include/CGAL/Conformal_map/internal/`. - Mark internal headers `\internal` for Doxygen (the parameters header already does this correctly โ€” `Conformal_map/internal/parameters.h` is the right pattern). ### Done when - Only the intended public headers are documented; the rest are under `internal/`. --- ## G10 โ€” ๐ŸŸก No demo / benchmark directory ### Evidence No `demo/` and no `benchmark/` directory. For a numerical package, CGAL reviewers appreciate (and for some packages expect) a benchmark establishing performance characteristics, and a small demo is a strong plus. ### Action - Add `benchmark/Discrete_conformal_map/` measuring solve time / iteration counts on the existing smoke meshes (cathead/brezel/brezel2) โ€” this also dovetails with the performance findings in `api-performance-audit-2026-05-31.md` (B1/B4). - A demo is optional; skip if time-constrained. ### Done when - A benchmark program exists and its numbers are referenced in the user manual. --- ## G11 โ€” ๐Ÿ”ต Public-API naming inconsistencies (cross-ref) The naming inconsistencies documented in `api-performance-audit-2026-05-31.md` (findings A1โ€“A5: `assign_*`, `compute_*`, `gradient_check`, the `_map` suffix, and the split result types) become **public-API-stability concerns** once the package is in CGAL, because CGAL APIs are expected to be stable across releases. Resolve A1โ€“A5 **before** submission, not after โ€” renaming a shipped CGAL API requires a deprecation cycle. ### Done when - A1โ€“A5 resolved; the public names are the ones intended to be permanent. --- ## G12 โ€” ๐Ÿ”ต File header boilerplate ### Evidence Headers begin with `// Copyright (c) 2024-2026 Tarik Moussa.` + a bare SPDX line. CGAL files use a standardized header including the `$URL$`/`$Id$` SVN/git keywords, the SPDX line in CGAL's form, and the copyright holder convention used in the tree. ### Action Adopt the CGAL file-header template (tied to the G1 license decision). Mechanical once G1 is settled. ### Done when - Headers match the CGAL file-header template. --- ## What is already strong (genuine assets for submission) - **Named-parameter API** is idiomatic: `CGAL::parameters::gradient_tolerance(...) .max_iterations(...)`, with the tag machinery correctly placed in `Conformal_map/internal/parameters.h` and marked `\internal`. This is the hard part done right. - **Doxygen group hierarchy** (`PkgConformalMap` / `Ref` / `Concepts` / `NamedParameters`) is set up correctly in `doxygen_groups.h`. - **The `\internal` discipline** on the parameters header shows the author knows the public/internal distinction โ€” it just needs to be applied to the other helpers (G9). - **Result types carry observability** (`sparse_qr_fallback_used`, iteration counts). - **Algorithmic breadth + validation**: five DCE models with Java golden-oracle parity and FD-gradient checks โ€” a strong scientific basis, which is ultimately what the editorial board cares most about. - **Traits-based design intent** is correct CGAL architecture; it only needs the genericity actually implemented (G7) and the concept properly documented (G4). --- ## Suggested order of work (submission track) 0. **G0 (porting rights)** โ€” owner-level legal precondition; contact the Varylab/TU-Berlin authors. **Nothing below should ship publicly until this is resolved.** 1. **G1 (license decision)** โ€” follows directly from G0; pick GPLv3+ if submission stays the goal. 2. **G2 + G3 + G8 (restructure)** โ€” do the layout move and header rename together; drop vendored CGAL on the submission branch. 3. **G9 (public/internal split)** โ€” naturally part of the restructure. 4. **G11 / A1โ€“A5 (lock the public names)** โ€” before any docs are written against them. *(A1โ€“A3 are internal-API renames and are safe to do independently of G0; A4โ€“A5 touch the public CGAL surface and should wait for the G0/G1 outcome.)* 5. **G4 + G5 (concept file + user manual + PackageDescription)** โ€” the doc deliverables. 6. **G6 (CGAL test harness)** โ€” port the 272 tests off GoogleTest. 7. **G7 (deliver or narrow genericity)**. 8. **G10 (benchmark)** + **G12 (headers)** โ€” polish. > Realistic framing for the owner: the **science is submission-grade**; the gap is > **packaging + licensing + doc-format**. None of items G2โ€“G12 require new research, > but collectively they are a significant, mostly-mechanical effort. G1 is a decision, > not work.