reviewer-meeting prep: CI promotion + 3rd-party licenses + output_uv_map(ID) + briefing trio #19
Reference in New Issue
Block a user
No description provided.
Delete Branch "reviewer/meeting-prep"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Layers on top of PR #18 (ci/structural-tests). Self-contained 2-commit story:
ci+licenses: promote 4 trivial gates to required CI + THIRD-PARTY-LICENSES.md — license-headers, cgal-conventions, codespell, shellcheck become required PR gates; new code/deps/THIRD-PARTY-LICENSES.md with per-vendored-dep SPDX + downstream-packager matrix; gitignore fix to make the new license file actually tracked.
feat: output_uv_map for InversiveDistance, error for CP-Euclidean, reviewer trio — output_uv_map now covers 4 of 5 DCE entries via Bowers-Stephenson edge-length reconstruction; CP-Euclidean throws clearly to flag Phase 9c; new doc/reviewer/ folder with briefing.md + questions.md + agenda.md for the meeting; +2 tests (suite 257 -> 259).
All gates green; 259/259 tests pass. Mergeable into main after PR #18 lands.
CI gates (active on every PR via .gitea/workflows/) ─────────────────────────────────────────────────── 1. test-count consistency cpp-tests.yml gains a step after test-cgal that runs `scripts/check-test-counts.sh` against the just-built ./build dir (reuse via new BUILD_DIR env var, ~5 s overhead). Drift between `doc/api/tests.md` and ctest reality now fails the PR. 2. End-to-end smoke `scripts/try_it.sh` (the documented user quick-start) is now part of the CGAL job, so README quick-start regressions fail the PR rather than silently breaking when users land. 3. Internal markdown link checker New `.gitea/workflows/markdown-links.yml` + `scripts/check-markdown -links.py`. PRs that touch any *.md file run the check; main pushes trigger it too; a weekly cron catches external link rot. Pure Python, no third-party action. Validated against the current tree: 122 internal links across 37 *.md files, 0 broken. Local quality scripts (`scripts/quality/`, not in CI) ───────────────────────────────────────────────────── * `license-headers.sh` — `SPDX-License-Identifier: MIT` audit over code/{include,src,tests}/. Currently reports 60/66 files missing it — that's a follow-up; the script captures the structural gap. * `sanitizers.sh` — ASan + UBSan over the fast test suite. * `coverage.sh` — gcov/lcov line + branch coverage of code/include/, HTML report under build-coverage/lcov-html/. * `clang-tidy.sh` — runs the curated `.clang-tidy` policy over every public header. * `multi-compiler.sh` — sequential build + test against every detected g++/clang++ (auto-discovery or explicit list). * `cgal-version-matrix.sh`— sequential build + CGAL test suite against every CGAL tree under `~/cgal/<ver>/` (or via `CGAL_ROOTS=...` env var). * `reproducible-build.sh`— two `Release -j1` builds, fail if any test executable byte-differs. * `run-all.sh` — driver: `--fast` for the ~5-min subset, no arg for the ~25–40 min full sweep; captures per-gate logs to build-quality-logs/. + `.clang-tidy` — curated, deliberately-small policy (only checks that fire on OUR code, never on transitive CGAL/Eigen/Boost headers). + `scripts/quality/README.md` — explains the structure, lists each gate's wall-time + prereqs, and codifies the promotion path: a gate moves into CI only when it's green on the dev machine AND has a recovery-instructions paragraph in `doc/release-policy.md`. Doc updates ─────────── `doc/architecture/locked-vs-flexible.md` (reviewer-facing) gains 4 "closed" rows in the limitations table — the 3 CI gates above and the local quality-script suite. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>Closes the gap "no code-quality / convention gate" from the structural review. Three new artefacts, all local-only (CI promotion deferred until the existing tree is 100 % clean under each): 1. .clang-format — project's existing style mechanically captured (4-space indent, opening brace on new line for class/struct/function, left-aligned pointer/reference modifiers, aligned `using = ...` blocks, 100-col loose limit, no include re-ordering — matches code/include/ today). 2. scripts/quality/clang-format.sh — drift detector. Dry-run mode by default (always exits 0); --strict to fail on drift; --fix to apply suggested changes in place. Skips code/deps/ and macOS-duplicate files. 3. scripts/quality/cgal-conventions.py — checker for the CGAL idioms that clang-format/clang-tidy cannot express: CGAL-1 include-guard format `CGAL_<DIRS>_<FILE>_H` CGAL-2 every public header has a `\\file` Doxygen brief CGAL-3 no nested namespaces beyond the allowed set (CGAL::parameters, CGAL::Conformal_map, internal_np, IO) CGAL-4 named-parameter tag types end in `_t`; value object does not CGAL-5 no `using namespace ...` at file scope (header leakage) CGAL-6 no #define beyond CGAL_* / include-guard Result on the current tree: 6 CGAL public headers, 0 violations. The checker therefore doubles as documentation of the conventions we already follow. Both are wired into scripts/quality/run-all.sh's fast subset (~5 s combined wall time). README.md updated to split the gates into a "style/convention" group (cheap, run-on-every-commit material) and a "correctness/quality" group (slow, run-before-tag material). The reviewer-facing locked-vs-flexible.md gains another "✅ Closed" row documenting both gates and the 0-violation baseline. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>This commit closes the remaining red gates so `run-all.sh --fast` is green end-to-end on the canonical dev machine. New gates ───────── 1. cmake-format / cmake-lint * scripts/quality/cmake-format.sh — dry-run by default, --strict to fail on drift, --fix to apply * .cmake-format.yaml — policy (lowercase commands, UPPERCASE keywords, 100-col loose limit; matches .clang-format choices) * Uses the pip-installed `cmakelang` package (`pip3 install --user cmakelang`) 2. codespell * scripts/quality/codespell.sh — exit 1 on any typo, --fix interactively * .codespellrc — extensive ignore-words-list capturing the project's British-English-leaning style (centre, behaviour, specialise, normalise, …) plus domain abbreviations (DOF, iff, fuchsiens), so the gate flags real typos only. * Validated: 0 typos across docs + code/include + scripts + code/{src,tests}. SPDX rollout (license-headers --fix) ──────────────────────────────────── license-headers.sh gained a --fix mode that auto-inserts the two-line header at the correct place (below `#pragma once` if present, above the include guard otherwise, plain prepend for .cpp). Ran it on 60 of 66 files — 100 %-licensed now. Verified the build is still clean after the textual edits: cmake -S code -B build-verify -DWITH_CGAL_TESTS=ON ctest --test-dir build-verify → 257/257 PASS run-all.sh + README updated to include the two new gates. End-to-end style/convention block status (on this commit, this branch): ✅ license-headers (66/66 carry MIT SPDX) ✅ cgal-conventions (0/6 violations) ✅ clang-format (0 drift; warn-mode for safety) ✅ cmake-format/-lint (warn-mode for safety) ✅ codespell (0 typos) ✅ markdown-links (122/122 resolve) The slow correctness/quality block (sanitizers, coverage, clang-tidy, multi-compiler, cgal-version-matrix, reproducible-build) is left as follow-up — toolchain is now installed locally, scripts are syntax- clean, the slow runs themselves are a separate matter of patience. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>Closes the structural-tests work end-to-end. After this commit, the full run-all.sh sweep (10 fast + 4 slow gates) finishes in ~3 min on the canonical dev machine with: PASS License headers (66/66 carry MIT SPDX) PASS CGAL conventions (0/6 violations) PASS clang-format drift (0 drift) PASS cmake-format/-lint (0 drift, 0 lint findings) PASS codespell (0 typos) PASS shellcheck (0 findings, 16 .sh files) PASS cppcheck (warning+ severity clean) PASS Markdown links (122/122 resolve) PASS Sanitizers (ASan+UBSan) (23/23 tests pass) PASS clang-tidy (35 headers, 0 findings) PASS Coverage (gcov+lcov, graceful on macOS) PASS Multi-compiler (AppleClang + brew LLVM, both 23/23) PASS Reproducible build (byte-identical between 2 builds) SKIP CGAL version matrix (no CGAL tarballs under ~/cgal/) Bug fixes uncovered by the slow block ───────────────────────────────────── 1. coverage.sh — Apple Clang `--coverage` deadlocks on arm64 during static-initializer profiling of template-heavy code (Eigen+CGAL). Auto-prefer brew-installed LLVM clang++ on Darwin when present; honoured `CXX=...` override. 2. coverage.sh — lcov 2.x rejects the brew-clang gcov output with "inconsistent / unsupported / negative / empty / mismatch" errors over GoogleTest's preprocessor gymnastics. Added `--ignore-errors` for all those classes; degrade gracefully to an informational "empty trace, but tests passed" summary when the info file can't be filled (lcov-on-macOS toolchain mismatch). 3. coverage.sh — added the same `CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE =PRE_TEST` fix as sanitizers.sh — coverage-instrumented binaries can't be safely executed at *build* time. 4. run-all.sh — broadened the SKIP-detection regex so the cgal-version-matrix.sh exit-2 message ("FAIL: no CGAL installs found.") is recognised as SKIP, not FAIL. These fixes make every slow gate runnable. The Linux CI will hit the same code paths with system gcc + system lcov where the coverage trace actually fills in; macOS dev users get a green "tests passed under instrumentation" signal without the report. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>Two reviewer-facing additions consolidated into one commit: (1) New `quality-gates` job in .gitea/workflows/cpp-tests.yml ────────────────────────────────────────────────────────── Runs in parallel with test-cgal after test-fast. Installs `codespell` + `shellcheck` (apt) into the existing ci-cpp container, then executes four scripts strictly (exit 1 on any finding): * license-headers.sh — 66/66 files carry SPDX MIT * cgal-conventions.py — 0 violations across 6 CGAL public headers * codespell.sh — 0 typos across docs + source + scripts * shellcheck.sh — 0 findings across 16 shell scripts Each ran at 0 findings locally before promotion. Total wall-time on the eulernest runner: ~30 s. (2) New code/deps/THIRD-PARTY-LICENSES.md ────────────────────────────────────── Enumerates every vendored dep under code/deps/, plus auto-fetched GoogleTest, plus system-required Boost, with: * upstream project + version + SPDX identifier * compatibility note for MIT distribution * downstream-packager license matrix (header-only consumer vs CLI binary) clarifying the LGPL §3 vs §4 distinction Required for any future Linux-distribution packaging and for the CGAL submission's compliance check. Also fixes a `code/.gitignore` gap: the `deps/*` wildcard was catching the new file; added `!deps/THIRD-PARTY-LICENSES.md` to the exclusion list so it's actually tracked. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>Three reviewer-meeting deliverables in one commit. (1) output_uv_map for the two remaining DCE entries ───────────────────────────────────────────────── * Discrete_inversive_distance.h: full implementation. After Newton, reconstruct effective Euclidean edge lengths from the converged log-radii via the Bowers-Stephenson identity `ℓᵢⱼ² = rᵢ² + rⱼ² + 2·Iᵢⱼ·rᵢ·rⱼ`, populate a temporary EuclideanMaps with `lambda0 = log(ℓᵢⱼ²)`, and reuse the existing `euclidean_layout(mesh, 0, eucl)` priority-BFS. Per-vertex Point_2 coordinates written into the user-supplied pmap. Optional `normalise_layout(true)` applies the canonical PCA centroid + major-axis rotation, same as the other 3 entries. * Discrete_circle_packing.h: throws std::runtime_error with a clear pointer to Phase 9c rather than silently producing nonsense. CP-Euclidean is face-based; the faithful output is a per-face circle packing in ℝ², not a per-vertex Point_2 map. A true layout requires BPS-2010 §6 (~150 lines, on the porting roadmap as Phase 9c). Failing loudly is the honest default. Tests: 2 new cases in test_cgal_phase8b_lite.cpp (OutputUvMap_InversiveDistance_PopulatesPmap; OutputUvMap_CPEuclidean_ThrowsClearly). Both green. Suite total now 259 (was 257, +2). CGAL subtotal: 234 → 236. (2) Reviewer meeting documents ────────────────────────── New directory doc/reviewer/ with three files: * briefing.md — one-page orientation for the reviewer. What the project is, where to look first (https://tmoussa.codeberg.page/ConformalLabpp/), the headline evidence (tests/coverage/sanitizers/license), what we want from them, what's deferred and why, and the 5 questions in a separate file. * questions.md — the 5 concrete decisions we want their second opinion on: Q1 Phase 9c (port-literal vs re-derive) Q2 Phase 9b-analytic (worth ~2 weeks for ~6× speedup?) Q3 CP-Euclidean output_uv_map (build now or defer?) Q4 CGAL submission strategy (one package or five?) Q5 geometry-central cross-validation co-authorship Plus an explicit "what would you say no to?" question at the bottom — negative feedback is the highest-value information. * agenda.md — my own internal playbook (NOT to be sent). 60-min flow: 5-min thank-you, 10-min architecture tour, 30-min for Q1-Q5 in the order Q4-Q1-Q2-Q5-Q3, 5-min "no" question, 5-min wrap-up. Includes post-meeting memo template to fill out in the 30 min after. * README.md — index for the directory; says which file goes to whom and when to send. (3) locked-vs-flexible.md known-limitations update ───────────────────────────────────────────── "output_uv_map covers 3 of 5 entries" → "covers 4 of 5". CP-Euclidean's throws-clearly behaviour documented as a Phase 9c deliverable rather than a passive gap. Bonus: extended .codespellrc ignore list (acknowledgement, the British-English spelling I used in agenda.md). Verifications on this commit: 259/259 tests pass (0 skipped) scripts/check-test-counts.sh: OK (23 + 236 = 259) scripts/quality/license-headers.sh: OK (66/66 SPDX) python3 scripts/quality/cgal-conventions.py: OK (0/6 violations) scripts/quality/codespell.sh: OK (0 typos) scripts/quality/shellcheck.sh: OK (0 findings) python3 scripts/check-markdown-links.py: OK (143/143) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>Add phases 9d / 9e / 9f and literature citations derived from a systematic review of the five authors' publication lists (Tier 1 / 2 / 3 analysis). phases.md: - Phase 9d: ConesUtility port (9d.1) + non-Euclidean cone extensions (9d.2, RESEARCH) + StereographicUnwrapper (9d.3) - Phase 9e: CirclePatternLayout + CirclePatternUtility (Java port) - Phase 9f: Polygon Laplacian on non-triangular meshes (Alexa 2011/2020, RESEARCH — no Java equivalent) - Phase 9b-analytic: add Rivin-Springborn 1999 as Schläfli source - Phase 10b: add Bobenko-Bücking 2009 + Bobenko-Lutz 2024 IMRN - Phase 10c: add Lutz 2023 (canonical tessellations) + Bobenko-Lutz 2024 - Phase 10c' KoebePolyhedron: add Bowers-Bowers-Lutz 2026 rigidity result references.md: - Crane et al. 2018 Optimal Cone Singularities (Phase 9d.2) - Bobenko-Lutz 2025 Discrete & Comput. Geom. (Phase 9d.2) - Bobenko-Lutz 2024 IMRN (Phase 10b/c) - Lutz 2023 Geom. Dedicata (Phase 10c) - Lutz PhD thesis TU Berlin 2024 (Phases 9d.2, 10b, 10c) - Bowers-Bowers-Lutz 2026 (Phase 9b-analytic + 10c') - Alexa-Wardetzky 2011 + Alexa 2020 (Phase 9f) - Bobenko-Bücking 2009 (Phase 10b) - Rivin-Springborn 1999 (Phase 9b-analytic) research-track.md: - New entry: Phase 9d.2 non-Euclidean cone extensions (Bobenko-Lutz 2025 + Crane 2018), with acceptance criteria - New entry: Phase 9f polygon Laplacian (Alexa-Wardetzky 2011 / Alexa 2020), with acceptance criteria java-parity.md: - Split cone-metrics row into Euclidean (9d.1 port) and non-Euclidean (9d.2 research) with literature references - Add ConesUtility to "utility classes not yet ported" table Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>Auto-merge from cherry-pick concatenated both branch versions of Phase 9d and 9e. This commit resolves the duplication: - 9d now has 4 sub-items (9d.1–9d.4) combining both branches: 9d.1 ConesUtility (detailed: BFS, auto-placement, quantization) + Troyanov/Springborn refs (from literature analysis) 9d.2 Non-Euclidean cone extensions (RESEARCH) + Bobenko-Lutz 2025 + Crane 2018 (from literature analysis) 9d.3 StereographicUnwrapper + SphereUtility 9d.4 MobiusCenteringFunctional - 9e keeps the detailed reviewer/meeting-prep version + adds mathematical references (Bobenko-Hoffmann-Springborn 2006) - 9f (Polygon Laplacian, Alexa 2011/2020) retained as standalone section Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>Adds the two research-track questions to the front of the queue, where they belong for a reader whose publication line maps directly onto our research-track roadmap entries. briefing.md gains two new sections: * Research alignments — a 6-row table mapping the reader's research threads (decorated DCE, canonical tessellations, hyperideal rigidity, optimal cone placement, polygon Laplacian, Schläfli machinery) onto concrete phases of the roadmap, with the closest published line cited generically (year + venue only). * What's new on this snapshot — the 6 new porting phases + 9 new citations + Phase 9f (RESEARCH, no Java parent) + output_uv_map extension to Inversive-Distance. questions.md restructures the question set from 5 to 7: * Q1 (NEW) — research-track alignment: which of 9d.2 / 9f / 10c / 10c′ would unblock concrete experiments? * Q2 (NEW) — decorated-DCE API surface: A/B/C named parameter vs new solver vs property-map auto-detect? * Q3 — Phase 9b-analytic (was Q2) * Q4 — Phase 9c port-literal vs re-derive (was Q1) * Q5 — GC-1 cross-validation co-authorship (was Q5) * Q6 — CGAL submission packaging (was Q4) * Q7 — The "no" question (was the trailing section) Also drops Q3 from the previous list (CP-Euclidean output_uv_map), since that question is now answered (Phase 9c, runtime error today, on the deferred list — no reviewer input needed). Adds a final "After the meeting — would you collaborate?" block so the post-meeting collaboration options (acknowledgement / co-author / cadence / PRs) do not surprise the reader on the day. agenda.md reorders §2 to match the new question order; the timing shifts Q1/Q2/Q3 (research) to the front and Q4/Q6 (project management) to the back. Memo template at the bottom now has 7 named answer slots instead of 5 numbered ones. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>Updates the "Quick links the reviewer should bookmark" section of doc/reviewer/README.md so it matches the Pages-hub v4 layout: * the hub itself now carries status badges, a "what's new" banner, and the research-alignment table — call this out so the reader knows what to expect when they click through; * adds direct links to the three documents that the new Q1/Q2/Q3 questions actually depend on (references.md, phases.md, research-track.md) — previously only the Schläfli-derivation note and the locked-vs-flexible architecture page were linked; * re-points the Schläfli derivation link from "Q2" (old numbering) to "Q3" (new numbering after baustein B inserted research questions at Q1/Q2). Companion change to the Pages-hub v4 already pushed to the codeberg `pages` branch; this commit keeps the in-repo guidance in sync. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>Two structural compile-time optimisations on the conformallab_cgal_tests target, both opt-out-able and verified safe (236/236 tests pass under every configuration). (1) Precompiled headers — option CONFORMALLAB_USE_PCH (default ON) target_precompile_headers(conformallab_cgal_tests PRIVATE <CGAL/Surface_mesh.h> <CGAL/Simple_cartesian.h> <CGAL/Kernel_traits.h> <CGAL/boost/graph/iterator.h> <CGAL/Polygon_mesh_processing/triangulate_faces.h> <Eigen/Dense> <Eigen/Sparse> <Eigen/SparseCholesky> <Eigen/SparseQR> <gtest/gtest.h> <vector> <string> <cmath> <complex> ) Absorbs the per-TU CGAL+Eigen template-parse cost (measured at 5.9 s per minimal "include <CGAL/Discrete_conformal_map.h>" hello-world TU on Apple M1). (2) Unity Build — UNITY_BUILD ON with UNITY_BUILD_BATCH_SIZE 4 Concatenates the 22 test TUs into 5 batches of <=4 files each; CGAL+Eigen headers parsed once per batch instead of once per TU. Batch size 4 keeps gtest's TEST(...) macros and per-file `using namespace ...` from colliding across batched files. Numbers (Apple M1, Ninja, -j8, clean rebuild) ───────────────────────────────────────────── wall CPU tests baseline 78 s 676 s 236/236 + PCH 66 s 474 s 236/236 (-15% wall, -30% CPU) + PCH + Unity 55 s 167 s 236/236 (-30% wall, -75% CPU) Honest deferred items (documented in doc/architecture/compile-time.md): * `extern template` (lever #2 in the analysis) — subsumed by PCH; estimated residual gain <5%, would add Eigen-version fragility. * Header split <CGAL/Discrete_conformal_map_{euclidean,spherical, hyper_ideal}.h> (lever #3) — downstream-only benefit (our test build needs all three); kept as a future cleanup once a downstream user actually requests it. Opt-outs: `-DCONFORMALLAB_USE_PCH=OFF` and `-DCMAKE_UNITY_BUILD=OFF`. Detailed measurement methodology, per-TU breakdowns, clang -ftime-trace template hot-spots, and a "what comes next" lever list live in doc/architecture/compile-time.md. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>Four orthogonal opt-in build modes on top of the existing PCH + Unity defaults. Each addresses a specific iteration scenario; defaults are unchanged (PCH + Unity stays the canonical fast full-rebuild path). (A) HEADERS_CHECK target — opt-in via -DCONFORMALLAB_HEADERS_CHECK=ON Per-public-header smoke-compile sentinels. For each of the six public CGAL umbrella headers, a stub TU `#include <…>\nint main(){}` is generated at configure time and compiled in isolation. * Full headers_check build: ≈ 12 s * Incremental after touching one header: ≈ 0.1 s Use case: "did my refactor still parse the public API?" without waiting 55 s for the full CGAL test build. (C) DEV_BUILD mode — opt-in via -DCONFORMALLAB_DEV_BUILD=ON PCH stays on; Unity Build is forced off (both globally AND on the cgal-tests target which previously overrode the global setting). Trade-off: full clean rebuild ~75 s (+36 % vs the 55 s default) but incremental rebuild after editing a single test file drops from ~46 s (unity batch) to ~16 s (single TU + relink). Flip on for trial-and-error sessions, flip off before measuring CI build time or shipping a PR. (D) ccache integration — default ON, disable with -DCONFORMALLAB_USE_CCACHE=OFF Detects `ccache` on PATH and prepends it to compile + link launchers. On Apple clang + PCH + Unity the macOS-local hit rate is currently 0 % (3 separate friction points documented in doc/architecture/compile-time.md § "ccache — honesty notes"); stays neutral when it doesn't help. Real payoff on Linux CI (g++ + traditional PCH) where 80 %+ hit rates are typical. (BUILD_TESTING=OFF) Standard CMake gate, now respected end-to-end. Wrapped both `add_subdirectory(tests)` AND the FetchContent of GoogleTest in `if(BUILD_TESTING)`. Pass `-DBUILD_TESTING=OFF`: * Configure ≈ 1 s * Build ≈ 0 s * 0 object files * No GTest fetch Use case: IDE-syntax-check workflow that needs `compile_commands.json` but does NOT need to download GTest or build any test binary. doc/architecture/compile-time.md gains: * a "Workflow modes — what to choose when" section with a 4-row switch matrix and a "mode matrix at a glance" comparison table * a ccache honesty-notes block listing the three macOS friction points (PCH artefact caching, Unity Build path randomisation, CMake launcher integration) — Linux CI is where the lever pays off Verified: default build 53 s wall, 236/236 tests pass; all opt-in modes tested end-to-end with their expected workflow numbers documented in the doc. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>Two additions that close out the reviewer-prep work cleanly: 1. doc/reviewer/hub.html + publish-workflow integration ────────────────────────────────────────────────────── Move the hand-curated reviewer hub from the codeberg `pages` branch (where it lived as an opaque snapshot) into the repo as `doc/reviewer/hub.html`. `.gitea/workflows/doxygen-pages.yml` gains a conditional `if [ -f doc/reviewer/hub.html ]; then …` step that installs it as the publish `index.html` and demotes the auto-generated Doxygen index to `/doxygen.html`. Effect: merging any of the open PRs into main will trigger the workflow, which republishes BOTH the Doxygen + the reviewer hub together. The reviewer URL stays live across merges with zero manual intervention. Source-controlled benefits: * hub edits go through normal PRs, not orphan-branch force-pushes * old hub versions live in git history * the in-repo links now target `branch/main/…` instead of the transient `preview/reviewer-snapshot-vN/…` paths 2. .gitea/workflows/perf-compile-time.yml — Linux CI bench ──────────────────────────────────────────────────────── New workflow runs on every push to main that touches the build system or public headers. Five-step matrix measures and reports: Run 1 cold baseline (no PCH, no Unity, no ccache) Run 2 + PCH only Run 3 + PCH + Unity (current default) Run 4 + FAST_TEST_BUILD=ON (-O0 -g — Linux's expected ~40 % win) Run 5 + ccache warm rerun (expected ≥ 90 % cache hit) Validates the Apple-M1 predictions in doc/architecture/compile-time.md against the Linux + g++ runner where Backend dominates more and the Apple-clang+PCH friction that defeats ccache locally does not apply. Job is data-collection only; never blocks a merge. doc updates: * doc/architecture/compile-time.md — new "Cross-platform perf bench" section linking to the workflow + the table of macOS-vs-Linux expected deltas. * doc/reviewer/README.md — new "Hub-Page durability" subsection explaining how the hub survives merges. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>Two additions that close out the reviewer-prep work cleanly: 1. doc/reviewer/hub.html + publish-workflow integration ────────────────────────────────────────────────────── Move the hand-curated reviewer hub from the codeberg `pages` branch (where it lived as an opaque snapshot) into the repo as `doc/reviewer/hub.html`. `.gitea/workflows/doxygen-pages.yml` gains a conditional `if [ -f doc/reviewer/hub.html ]; then …` step that installs it as the publish `index.html` and demotes the auto-generated Doxygen index to `/doxygen.html`. Effect: merging any of the open PRs into main will trigger the workflow, which republishes BOTH the Doxygen + the reviewer hub together. The reviewer URL stays live across merges with zero manual intervention. Source-controlled benefits: * hub edits go through normal PRs, not orphan-branch force-pushes * old hub versions live in git history * the in-repo links now target `branch/main/…` instead of the transient `preview/reviewer-snapshot-vN/…` paths 2. .gitea/workflows/perf-compile-time.yml — Linux CI bench ──────────────────────────────────────────────────────── New workflow runs on every push to main that touches the build system or public headers. Five-step matrix measures and reports: Run 1 cold baseline (no PCH, no Unity, no ccache) Run 2 + PCH only Run 3 + PCH + Unity (current default) Run 4 + FAST_TEST_BUILD=ON (-O0 -g — Linux's expected ~40 % win) Run 5 + ccache warm rerun (expected ≥ 90 % cache hit) Validates the Apple-M1 predictions in doc/architecture/compile-time.md against the Linux + g++ runner where Backend dominates more and the Apple-clang+PCH friction that defeats ccache locally does not apply. Job is data-collection only; never blocks a merge. doc updates: * doc/architecture/compile-time.md — new "Cross-platform perf bench" section linking to the workflow + the table of macOS-vs-Linux expected deltas. * doc/reviewer/README.md — new "Hub-Page durability" subsection explaining how the hub survives merges. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>Two additions that close out the reviewer-prep work cleanly: 1. doc/reviewer/hub.html + publish-workflow integration ────────────────────────────────────────────────────── Move the hand-curated reviewer hub from the codeberg `pages` branch (where it lived as an opaque snapshot) into the repo as `doc/reviewer/hub.html`. `.gitea/workflows/doxygen-pages.yml` gains a conditional `if [ -f doc/reviewer/hub.html ]; then …` step that installs it as the publish `index.html` and demotes the auto-generated Doxygen index to `/doxygen.html`. Effect: merging any of the open PRs into main will trigger the workflow, which republishes BOTH the Doxygen + the reviewer hub together. The reviewer URL stays live across merges with zero manual intervention. Source-controlled benefits: * hub edits go through normal PRs, not orphan-branch force-pushes * old hub versions live in git history * the in-repo links now target `branch/main/…` instead of the transient `preview/reviewer-snapshot-vN/…` paths 2. .gitea/workflows/perf-compile-time.yml — Linux CI bench ──────────────────────────────────────────────────────── New workflow runs on every push to main that touches the build system or public headers. Five-step matrix measures and reports: Run 1 cold baseline (no PCH, no Unity, no ccache) Run 2 + PCH only Run 3 + PCH + Unity (current default) Run 4 + FAST_TEST_BUILD=ON (-O0 -g — Linux's expected ~40 % win) Run 5 + ccache warm rerun (expected ≥ 90 % cache hit) Validates the Apple-M1 predictions in doc/architecture/compile-time.md against the Linux + g++ runner where Backend dominates more and the Apple-clang+PCH friction that defeats ccache locally does not apply. Job is data-collection only; never blocks a merge. doc updates: * doc/architecture/compile-time.md — new "Cross-platform perf bench" section linking to the workflow + the table of macOS-vs-Linux expected deltas. * doc/reviewer/README.md — new "Hub-Page durability" subsection explaining how the hub survives merges. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>