Skip to content

chore: repo cleanup (static analysis sweep) - #268

Draft
domattioli wants to merge 65 commits into
mainfrom
dev-cleanup
Draft

chore: repo cleanup (static analysis sweep)#268
domattioli wants to merge 65 commits into
mainfrom
dev-cleanup

Conversation

@domattioli

Copy link
Copy Markdown
Owner

Summary

A static-analysis sweep over src/chilmesh, tests, and scripts using ruff, vulture, radon, bandit, and pip-audit. Findings that could be fixed mechanically without judgement calls are fixed here; everything requiring a design decision is filed as an issue instead of being changed under a cleanup label.

Branch note: this work is on dev-cleanup rather than development as an explicit operator-authorized carve-out for this sweep.

What the scan found

Tool Findings
ruff (F, E) 782
bandit 38 (11 MEDIUM, 27 LOW)
radon 11 functions at rank D or E
vulture (confidence ≥ 80) 1
pip-audit 9, all against pip/setuptools in the scan virtualenv, none against project dependencies

Fixed here (3 commits)

Real defects. src/chilmesh/gmsh_io.py referenced CHILmesh in four return annotations without importing it (F821). Because the module uses from __future__ import annotations these never raised at runtime, but they broke any tooling that resolves the annotations. Fixed with a TYPE_CHECKING import.

Error handling. Four bare except: clauses in scripts/github_release.py and scripts/pypi_publish.py were swallowing KeyboardInterrupt and SystemExit during release operations. Narrowed to except Exception:.

Dead code. Removed unused imports and locals: four top-level imports in CHILmesh.py (including a top-level spsolve shadowed by the local import inside direct_smoother), one unused typing import in bridge.py, three unused local imports in gmsh_io.py, and unused imports plus redundant f-string prefixes across the scripts and test suite. Two fort.14 boundary-count parses were renamed to _ so the parse cursor still advances while the discarded value is explicit.

Net effect: ruff findings drop from 782 to 711, and the F821, F541, F811, and E722 classes go to zero. Remaining F401 findings are two intentional availability probes.

Deliberately not fixed

Issues filed

No issues were closed.

Testing

pytest -k 'not block_o' before and after: 1488 passed, 79 skipped, 103 deselected, identical in both runs. The block_o fixture was deselected for runtime, as is standard for this suite.

Constraints held: no public API signature changed, no change to _skeletonize() behavior, no change to fort.14 I/O semantics, and no change to adjacency invariants.


Generated by Claude Code

domattioli and others added 30 commits July 10, 2026 13:46
read_fort14_raw gains parse_boundaries: bool = True. With False it returns
after the node/element table (empty boundaries), so identity consumers that
keep their own boundary parser (Valence #214) avoid the boundary-block parse
that raises on `=`-prose NOPE/NBOU headers in 10 of the 41 corpus meshes.

Element vertex tokens now parse via int(float(v)), tolerating float-formatted
integer indices (`1.000000`) present in structuredMesh1-4.

Default behavior unchanged (back-compat). Corpus table-only reads: 27/41 -> 41/41.
Unblocks Valence fort.14 read delegation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XoyeVJQshr8dMi41Pk2Rbm
Extend the int(float()) leniency from element vertices (prior commit) to the
NE/NP header counts and the node-id / element-id / arity columns, so a fort.14
written with uniform float formatting (`1.000000 0.0 0.0 1.0`) parses. Covers
Valence's float_ids.14 fixture end-to-end, letting the Valence adapter drop its
own file-normalizing fallback. Corpus table-only stays 43/43; ids are integers
so int(float(tok)) is exact.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XoyeVJQshr8dMi41Pk2Rbm
#251)

smooth_mesh declared *kwargs (single star) → collected extra positional
args and forwarded positionally; keyword smoother options (n_iter, omega,
freeze_quad_nodes) raised TypeError. Change to keyword-only sdf/size_fn +
**kwargs; forward as direct_smoother(**kwargs)/angle_based_smoother(**kwargs).
Add TestSmoothMeshKwargPassthrough regression (2 cases).
…d boundary blocks (#253)

Default-mode read_fort14_raw raised Fort14ParseError on 10/41 Valence corpus
meshes: int(parts[1]) choked on '='-prose ibtype tokens, and declared
boundary counts exceeding the block hit IndexError (Baranja_Hill, donut).
Add _lead_int() helper (leading-integer extraction, ignore trailing prose)
for ibtype parsing; guard both boundary loops + node loops against EOF
overrun. Add 2 regression tests.
…ce (#241)

New additive module src/chilmesh/geometry.py mirroring quality.py raw-array
style: haversine_m (vectorized, metres, mean-Earth-radius, clamped asin) and
edge_lengths(p1, p2, crs='cartesian'|'spherical') — planar Euclidean in
native units or geodesic metres for lon/lat degrees. CRS caller-declared;
resolvable from fort.15 ICS (Fort15.ics). Exported at package level.
15 tests (equator degree, antipodal clamp, 3-4-5, vectorized, error paths,
import surface). Upstreamed from Valence per #241.
…distance (#240)

Five pure-numpy primitives appended to geometry.py (no new deps):
convex_hull (Andrew's monotone chain, CCW, collinear-dropped),
is_antimeridian_wrapping / split_antimeridian_bbox (dateline-aware bbox
handling), bbox_iou (antimeridian-aware via east/west split), and
hausdorff_distance (discrete symmetric, cartesian or spherical/haversine).
Package-level exports. 27 new tests (40 total in test_geometry.py).
Upstreamed from Valence per #240.
Add courant_number(points, edges, depths, dt, crs) — per-edge shallow-water
Courant C = sqrt(g*h)*dt/dx (h = deeper endpoint depth, dx from geometry
edge_lengths honouring cartesian/spherical CRS); NaN for dry (h<=0) or
degenerate (dx<=0) edges. Add cfl_gate(...) wrapper: pass/fail flag vs
courant_max with max/median/p95 stats + worst-offender list. Both raw-array
(numpy-only), exported at package level, mirroring element_quality style.
19 new tests. Upstreamed from Valence gates.py per #238.
…ize reserved for medial-axis

Operator-ratified 2026-07-10 (math frame: stored ring = discrete level set;
construction = onion peeling; front-collision locus = medial axis, distinct).

Renames (clean, no compat aliases — no consumers yet):
- _layerize -> _peel (private port of MATLAB meshLayers)
- new public peel_layers() -> returns self.layers
- reskeletonize_local -> repeel_local; skeletonize_diff -> layers_diff
- _skeletonize alias deleted; all call sites -> _peel()
- 7 test files renamed (skeletoniz*/reskeletonize -> peel/repeel)
- prose sweep: 'skeletonization' -> 'peel/layer peel' across src, tests,
  scripts, docs (ARCHITECTURE, BENCHMARK, CONCEPTS, LEXICON_PROPOSAL)
- LEXICON_PROPOSAL.md rewritten as ratified decision record (caveman)

Reserved: 'skeletonize' now appears in code only as the compiled cpp/rust
backend extension API method (cross-language rename = backend release cycle)
and historical doc references. Future medial-axis op (#223) owns the name.

Verified: full fast suite 1423 passed / 79 skipped.
…, hero rework

- CHANGELOG: retitle shipped-but-unreleased [Unreleased] block as [1.3.0]
  (2026-07-04); add [2.0.0] section (breaking #187 lexicon renames +
  smooth_mesh signature fix; geometry module; CFL gate; fort14 robustness).
- pyproject 1.3.1 -> 2.0.0 (breaking renames, no compat aliases).
- CITATION.cff version 2.0.0, date-released 2026-07-10.
- README: sweep to ratified lexicon (peel/peel_layers; layerize retired);
  hero alt text updated to the new sequence.
- generate_hero_animation.py: rewritten schedule per operator + #198 —
  peel_layers reveal (input) -> quality crossfade -> ADMESH truss morph
  (positions+quality interpolated) -> FEM morph -> peel_layers reveal
  (smoothed), looping layers-to-layers. New facecolor blend/reveal helpers;
  render_view replaces render_frame.
…ted truss & FEM (#198)

New sequence: peel_layers() inward reveal on the input mesh -> element
quality crossfade -> ADMESH truss (node positions + quality interpolated
to convergence, #198) -> FEM smoother (interpolated) -> peel_layers()
reveal on the smoothed mesh, looping layers-to-layers. Quality histogram
visibly improves raw (median 0.491) -> smoothed (0.669).
…FEM/peel animation (#179)

distmesh2d_warmstart gains additive history_out=/history_every= per-iteration
snapshot capture ((points, triangulation) post-update; default off, no
behavior change; 2 regression tests incl. determinism vs no-capture run).

Hero animation rebuilt on real pipeline states only:
- Stage 0 Seed: boundary rings fade in, random interior nodes fall onto the
  paper (staggered), settle pause, wireframe of the scattered triangulation.
- Stage 1 Truss: playback of ACTUAL solver iterations at deltat=0.02 (the
  converging regime for a cold scattered seed — median q 0.38 -> 0.87 in ~15
  iterations; default deltat oscillates), early frames held 3x (slow-motion
  replay of real states), retriangulations included.
- Stage 2 FEM: Balendran smoother on the solver's real output mesh.
- Stage 3 Peel: held final peel_layers() view (no reveal frames).
Histogram y-axis pinned to global max bin count. 24.3 s loop.
…DME renders it

README displays the hero at width=720; the 1320px render was wasted bytes
and tripped GitHub's README image pipeline (raw path serves fine, client
render failed). Same animation, smaller payload.
…t kwargs, equal-motion pacing, peel reveal, size budget)
…provenance, real CHILmesh guard, 18f holds, T026/T027
read_fort15(deep=True) additionally parses NOLIBF..REFTIM (incl. NWP
nodal-attribute names, TAU0==-5 min/max branch, 3D IDEN skip) into new
Optional Fort15 fields. Best-effort: parse failure warns and leaves deep
fields None. raw_text + byte-preserving write_fort15 contract unchanged
(#201). Unblocks Valence CFL/completeness-gate field needs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NV4fDaJG9iDB12CV1nmgBm
Was pinned to startswith('1.'); package is 2.0.0 since the v2.0.0 prep
commit, so the assertion failed. Now matches any semver X.Y.Z.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NV4fDaJG9iDB12CV1nmgBm
Numpy-native, renumbering-tolerant matcher (identity fast-path + greedy
cKDTree spatial NN) + generic nodal_field_delta for bathymetric/resolution
deltas between two meshes. Ports Valence diff.py match_nodes; standalone,
does not touch the CHILmesh class. Exposes the interpolation/remap primitive
CHILmesh self-identified as missing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NV4fDaJG9iDB12CV1nmgBm
Extend summary() to fort.13 (grid name + NP + NAttr, 3-line read) and
fort.15 (RUNDES/RUNID, 2-line read). Fixes the mesh_read_guard reroute
target: large *.13 reads reroute to 'chilmesh summary <file>', which
previously raised Unknown mesh format. Advances the #201 frontmatter/
context-management track (text metadata, Python owns the binary payload).
Additive; no locked stage module touched. 6 new tests (29 pass).
Extend summary() to numpy array files: .npy reports shape/dtype/fortran_order
via mmap (no body load); .npz streams each zip member's .npy header off the
archive (numpy.lib.format.read_array_header_*) without reading array bodies.
Completes the mesh_read_guard reroute-target coverage for the numpy formats it
blocks (.msh still gapped — no fixture). Additive; no locked stage module. 8
new tests (37 pass).
domattioli and others added 29 commits July 14, 2026 13:39
…mendation

First like-for-like measurement of all three backends built from source
(76/76 equivalence tests pass -> Rust output-correct). Answers the standing
"does Rust make sense over C++/Python" question, including the pointed
"could Rust replace Python anywhere to improve perf" ask.

Findings (bundled fixtures, this machine):
- Full init: Rust ~3-5x faster than Python but ~2-5x SLOWER than C++ (~5x on
  Block_O). C++ still leads.
- Queries: RustMesh.get_vertex_edges rebuilds the edge list every call
  (O(n_elems+n_edges)/call) -> 100-1800x slower than C++/Python, scales with
  mesh. Reported, not fixed (docs-only eval).
- Conclusion: C++ is the acceleration path; Rust earns no perf niche over it,
  and no Python functionality is worth migrating to Rust for speed.

New: docs/RUST_EVALUATION.md (measured tables, methodology, replace-Python
analysis, recommendation). Updated README + BENCHMARK.md to replace stale
tbd/"skeletonization incomplete (#163 closed)" language with the measured
result and a pointer. ENPAC perf cells stay tbd (mesh not in repo, not run).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjbNQvHz6tW4G6ArqmLpsc
RustMesh.get_vertex_edges rebuilt the full canonical edge list on every
call (O(n_elems+n_edges)/call) -> 100-1800x slower than C++/Python and
scaling with mesh size (954us/call on Block_O). build_adjacencies now
precomputes a vertex->edge index once from the same to_edge2vert source
(so output stays bit-identical), and get_vertex_edges returns the cached
row. set_connectivity invalidates the cache.

Block_O vertex-edge lookup: 954us -> 0.32us (~3000x), now on par with /
faster than C++ (0.63us) and Python (0.46us). 76/76
tests/test_backend_equivalence.py pass; n_layers parity holds on all
fixtures.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjbNQvHz6tW4G6ArqmLpsc
…nsumers

- RUST_EVALUATION.md: query table gains before/after-fix column (Block_O
  954us -> 0.32us); finding #4.2 and recommendation #6 updated to "fixed";
  new section 5.1 "Default backend & opt-in" answers whether Rust can
  replace Python as the default (no: both compiled backends are opt-in
  source builds, auto-selection already prefers Rust>Python when built,
  and if you ship a prebuilt wheel you ship the faster C++ one).
- BENCHMARK.md: Rust note updated to O(1) queries (fixed).
- README: Rust bullet + backend row note the query fix; Backends section
  now states selection order (C++ -> Rust -> Python), that both compiled
  backends are source builds (Rust is not a lighter opt-in than C++), and
  that C++ is the one to build. Points to RUST_EVALUATION.md.

Docs only; pairs the fix commit 8efeee6.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjbNQvHz6tW4G6ArqmLpsc
Operator-directed direction (2026-07-14): freeze the Rust backend, keep its
benchmark data, and pursue prebuilt C++ wheels as the real "speed by default"
lever instead of a second compiled backend.

Freeze Rust (docs/status only — no backend code touched):
- new src/chilmesh_core/STATUS.md (FROZEN banner + rationale)
- README backend row + Backends prose, RUST_EVALUATION.md (status header +
  section 6), BENCHMARK.md note, rust_backend.py module docstring,
  DOWNSTREAM_MIGRATION_GUIDE.md, CHANGELOG (Unreleased) all mark FROZEN
- planning docs (008-DECISION, codebase/CONCERNS) get dated status banners
  pointing to the evaluation; history retained
- reconciled stale claims: "not recommended yet" removed; the old "Rust
  skeletonization incomplete" (#163, now closed) superseded

Kept: the crate, rust-equivalence CI job, equivalence tests, and all measured
benchmark data. Frozen = not developed further, not the recommended accelerator.

New docs/dev/PREBUILT_WHEELS_PLAN.md: phased plan to publish prebuilt
chilmesh-cpp binary wheels to PyPI so `pip install chilmesh[cpp]` gives the
C++ speedup with no user toolchain (Model A: separate published package +
optional extra; expand build-cpp-wheels.yml to macOS/Windows + a publish job).
Refs #229, #225, #234.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjbNQvHz6tW4G6ArqmLpsc
Copy-paste-ready but intentionally inert (documentation, not live workflow):
- A1: matrixed build-cpp-wheels.yml (ubuntu/macos/windows) with a real
  full_init smoke test instead of hasattr-only
- A2: publish-cpp-wheels.yml template, release/tag-gated, Trusted Publishing
  (OIDC) preferred, token fallback noted
- A3: chilmesh[cpp] optional extra + README one-liner

Explicitly staged: macOS/Windows legs (runner billing #225) and the PyPI
publish job (irreversible outward action) need operator sign-off before going
live; Linux-only build is free and safe to enable first. The cpp extra must
land with the publish, never before.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjbNQvHz6tW4G6ArqmLpsc
…ifference)

#1 Lexicon (#187): "skeletonization" is deprecated for the layer-peel operation
(reserved for the future medial-axis op #223). Repaired my own prose to say
"layer peel"/"peel"; kept the literal backend method name skeletonize() (its
cross-language rename is deferred) with an explicit note. Historical CHANGELOG
entries left as dated records.

#2 Documented WHY frozen + HOW Rust differs internally: added a findings item
(RUST_EVALUATION.md) and a section in chilmesh_core/STATUS.md — Python = flat
numpy arrays + dict adjacencies + EdgeMap; C++ = half-edge (DCEL); Rust =
quad-edge (Guibas-Stolfi). All three bit-identical on output; the quad-edge
experiment (008-DECISION) did not beat the C++ half-edge backend, so the
data-structure bet is the core reason for the freeze.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjbNQvHz6tW4G6ArqmLpsc
Patch release capturing this session's Rust query O(1) bugfix plus the backend
evaluation / freeze / prebuilt-wheels-plan docs. No public API change.

- pyproject.toml 2.0.0 -> 2.0.1 (__version__ derives from metadata; no code bump)
- CHANGELOG: Unreleased block promoted to [2.0.1] - 2026-07-14
- CITATION.cff: version 2.0.1, date-released 2026-07-14

Prep only — the git tag, GitHub release, PyPI upload, and Zenodo archive are
operator actions. v2.0.0 (PyPI/Zenodo) is left untouched (both immutable).
After Zenodo archives 2.0.1, update CITATION.cff to the Zenodo concept DOI
(per the note on that identifier).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjbNQvHz6tW4G6ArqmLpsc
…t 2.0.0)

Ground truth (PyPI + GitHub releases): the latest published version is v1.4.0
(2026-07-11); there is no 2.0.0 anywhere. The repo's "2.0.0" was a phantom —
commit 9ec7bd8 prepped it, but that content actually shipped as v1.4.0 (its
release notes list the #187 lexicon rename + geometry/CFL). My earlier 2.0.1
prep was built on that bad metadata. Corrected:

- pyproject.toml + CITATION.cff: 2.0.1 -> 1.4.1
- CHANGELOG: [2.0.1] -> [1.4.1]; the phantom [2.0.0] -> [1.4.0] (2026-07-11,
  matching the actual release) so ordering is coherent; opener no longer calls
  1.4.0 a "Major release" and notes it shipped as 1.4.0 under the
  no-known-consumers judgment
- prebuilt-wheels plan: stale "2.0.0" main-pkg version -> 1.4.x

Next release = 1.4.1 (patch: Rust query O(1) fix + docs; no API change).
v1.4.0 (PyPI/Zenodo) left untouched. Publishing the tag/release stays operator.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjbNQvHz6tW4G6ArqmLpsc
… + sync

main had 4 commits development lacked (staged-2.0.0 -> 1.4.0 renumber, PyPI
upload --skip-existing, README DOI link, the #252 base). Resolved 7 conflicts:

- pyproject.toml / CITATION.cff -> 1.4.1 (dev's patch layered over main's 1.4.0)
- CHANGELOG.md -> main's authoritative [1.4.0] entry (operator wording) with
  dev's new [1.4.1] section on top
- README.md -> keep dev's frozen-Rust table row + measured perf bullet; main's
  reworked hero / DOI badge / status changes preserved (non-conflicting)
- src/chilmesh/__init__.py -> dev's #255 lazy-load version (its _LAZY_ATTRS map
  covers every name main eager-imported; verified by import + test_lightweight_import)
- src/chilmesh/summary_io.py + tests/test_summary_io.py -> dev's added gmsh (.msh)
  and generic fort.NNN summary support (main lacked it)

Verified in a clean interpreter: chilmesh.__version__ == 1.4.1; all public
names resolve under the lazy loader; 114 tests pass (summary_io +
test_lightweight_import #255 + 76 test_backend_equivalence).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjbNQvHz6tW4G6ArqmLpsc
…hil + docs site; drop unshippable conda-forge

Rust layer-peel completion removed from Now (#163 closed, Rust frozen). conda-forge
dropped (blocked by the PolyForm Noncommercial license — conda-forge requires a
redistributable/open-source license). Date June->July.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjbNQvHz6tW4G6ArqmLpsc
Reconciled the three drifted DOIs (header badge 21313196, bibtex/CITATION.cff
20263854) to the latest-release DOI 21199161 via zenodo-publish --reconcile-doi.
Added a clickable Zenodo DOI badge + thesis badge row to the Citation section;
bumped the stale @software bibtex version 1.2.2 -> 1.4.1.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjbNQvHz6tW4G6ArqmLpsc
mesh_read_guard reroutes .grd reads to `chilmesh summary` and summary()'s
docstring lists .grd as supported, but no test asserted the reroute target
resolves. TestSummaryGrd guards the .grd → fort14 dispatch (summary_io.py:106).
tests/test_summary_io.py 36→37 passed.
…plit (#260)

_quad_quality and element_quality routed quad min_angle/max_angle through a
diagonal triangle split returning min-of-sub-triangle values, so max_angle
under-reported obtuse quads (a 128.66-deg corner read 90 deg) and min_angle
returned a triangulation artifact (45 deg for a 90-deg unit square). Both now
derive from the element's own four interior angles, matching the skew/eas
branches in the same function.

- quality.py: _quad_quality gains a min_angle/max_angle branch (raw angles,
  radians); element_quality routes both metrics to _quad_quality instead of
  splitting.
- tests: two bug-codifying split assertions rewritten to the raw values;
  add skewed-quad regression (max=128.66 / min=51.34 deg) from the issue repro.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FpaAKD7SoE8zSx2BEeAVTu
read_fort14_raw + CHILmesh.read_from_fort14 conflated a present-but-empty
NOPE/NBOU block (physically 0/0/0/0) with an absent boundary section, both
yielding empty segment lists with no way to tell them apart. Add an additive
boundaries_present flag (Fort14Raw field + CHILmesh instance attr) set True
only when the block is physically parsed; stays False when absent or when
parse_boundaries=False. Distinguishes a boundaryless mesh from one stripped
in its lineage (Valence #13/#216 downstream symptom).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UsjeLCBpMSbXMffrdkBiQe
Operator answered #247 item 1 (2026-07-12): currently unaffiliated
(previously PSU during modernization, OSU at initiation). Aligns
CITATION.cff with the README 'Unaffiliated' author line. Kubatko/OSU-CHIL
co-author entry unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01216xCkHDCNF1CMsoeqzPYA
The downstream migration guide (v1.0, 2026-04-27) documented only the
v0.1.1->v1.0.0 Mesh-alias migration and asserted 'existing code keeps
working' — but v1.4.0 shipped the #187 breaking renames with no aliases,
which that guide (cited by #257 as the rename-migration authority) never
covered. Add a prominent 'v1.4.0 Breaking Renames (#187)' section:
rename map (skeletonize->peel_layers, _skeletonize/_layerize->_peel,
reskeletonize_local->repeel_local, skeletonize_diff->layers_diff),
smooth_mesh keyword-only sdf/size_fn (#251), a cross-version getattr
shim, and pin guidance. Mapping verified against installed chilmesh
1.4.1. Version-compat table + header/footer refreshed. Docs-only.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018NbQPRUP1Z7n7iWgicuimW
)

Ran the like-for-like cross-language bench on EasternPacific_ENPAC2003
(531,680 elems), reachable from the Valence sibling checkout. Rust
full-init 11.98 s (== Python 11.89 s same-machine, ~15x slower than C++
0.803 s), quality 2 ms, n_layers=75 across all backends. Fast-init/peel
stay n/a (Rust does not expose fast_init separately, #163). Corrects the
stale 'mesh lives outside the repo' claim in README + RUST_EVALUATION.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VRrArhjkdyXw3fY2oqyvz6
…ontradiction (#223)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PDT2YZgEu6DoXPKMzHCd85
…#256)

Phase 1a of #256 asked for a real full_init smoke, not just a symbol
probe. The cibuildwheel CIBW_TEST_COMMAND now builds a 2-triangle unit
square, calls chilmesh_cpp.full_init, and asserts the built adjacency +
skeleton (4 verts / 2 elems / 5 edges / adjacency_built / >=1 layer /
edge2vert shape (5,2)) so an empty or broken binary fails the build.
Adds CIBW_TEST_REQUIRES=numpy for the array inputs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018z9MobkyDkCqHasxikpEpi
Wire the Phase 2 PyPI publish pipeline for the chilmesh_cpp binary backend:
manylinux wheels (reusing the Phase 1a cibuildwheel + full_init smoke) + sdist,
gated on GitHub release / manual dispatch only (no push trigger, so nothing
publishes from development). Uses PyPI Trusted Publishing (OIDC) with a
commented token fallback; publish job protected by environment: pypi. macOS and
Windows legs stay deferred to Phase 1b (#225 billing gate). Registered in
LOCAL.md per spec-010 v3 creation gate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0176pc8LGNFpQZ9Kj6RU9ht9
Advance-only research note for the size-controlled cartogram request: maps the
proposed mesh.cartogram(kind=noncontig|unrolled|hybrid) API onto the current
chilplotting (plot_filled/build_polygons) + layer_paths (paths_on_outer_vertices)
+ mesh.layers substrate, with per-kind algorithm, validation plan, tiered backlog,
and four operator questions that would turn it status: ready. No implementation
(brainstorming entitlement: advance only, no label flip).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0176pc8LGNFpQZ9Kj6RU9ht9
…us (#261)

Repo is v1.4.1; the doc still describes the 2026-04-26 v0.1.1->v0.2.0
plan with obsolete 'You are here' Phase-0 markers. Adds a staleness
banner routing readers to README Status & Roadmap; content preserved
as historical record. Retire-vs-refresh disposition left to operator
per #261.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PDcuGMABcfwCuGuuKzpVPn
Drops four unused top-level imports from CHILmesh.py (matplotlib.pyplot,
matplotlib.cm, scipy.sparse.lil_matrix, and the shadowed top-level spsolve,
which direct_smoother already imports locally), one unused adjacency lookup,
and an unused typing import in bridge.py. Renames two fort.14 boundary-count
parses to _ so the cursor advance is preserved while the discarded value is
explicit.

Adds a TYPE_CHECKING import of CHILmesh to gmsh_io.py, resolving four F821
undefined-name findings on its return annotations, and removes three local
CHILmesh imports that were never used. The validation-only locals in the
gmsh parsers are intentionally retained; see the tracking issue.

No public API signature, _skeletonize behavior, fort.14 I/O semantics, or
adjacency invariant is affected.
Converts four bare 'except:' clauses in github_release.py and pypi_publish.py
to 'except Exception:', so KeyboardInterrupt and SystemExit are no longer
swallowed during a release run. Also removes unused imports and f-string
prefixes flagged by ruff across the benchmark, animation, and scene scripts.

Behavior is otherwise unchanged.
Applies ruff's safe fixes for F401, F541, and F811 across tests/. No test
logic, assertion, or fixture is modified. Assigned-but-unused locals are
left alone: in test code they often indicate a missing assertion rather
than dead code, and are tracked separately.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant