chore: repo cleanup (static analysis sweep) - #268
Draft
domattioli wants to merge 65 commits into
Draft
Conversation
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.
…ng, culling, peel reveal, metric keys)
…in-place histogram, mean=red
…t kwargs, equal-motion pacing, peel reveal, size budget)
…ain, scripted SC audits)
…provenance, real CHILmesh guard, 18f holds, T026/T027
…ss/T_truss provenance, prose sync
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).
…(spec 002 FR-001)
…cked histogram, color-keyed metrics (spec 002)
…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
… no MEX) 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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A static-analysis sweep over
src/chilmesh,tests, andscriptsusing 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-cleanuprather thandevelopmentas an explicit operator-authorized carve-out for this sweep.What the scan found
F,E)pip/setuptoolsin the scan virtualenv, none against project dependenciesFixed here (3 commits)
Real defects.
src/chilmesh/gmsh_io.pyreferencedCHILmeshin four return annotations without importing it (F821). Because the module usesfrom __future__ import annotationsthese never raised at runtime, but they broke any tooling that resolves the annotations. Fixed with aTYPE_CHECKINGimport.Error handling. Four bare
except:clauses inscripts/github_release.pyandscripts/pypi_publish.pywere swallowingKeyboardInterruptandSystemExitduring release operations. Narrowed toexcept Exception:.Dead code. Removed unused imports and locals: four top-level imports in
CHILmesh.py(including a top-levelspsolveshadowed by the local import insidedirect_smoother), one unused typing import inbridge.py, three unused local imports ingmsh_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, andE722classes go to zero. RemainingF401findings are two intentional availability probes.Deliberately not fixed
gmsh_io.pyunused locals. SevenF841findings there are validation-only parses whoseint()call exists to raiseValueErrorfor the surrounding handler. Deleting them would remove input validation from the.mshreader. Filed as chore: keep the gmsh reader's validation-only parses but silence the F841 warnings #266 so a future pass does not "fix" them.E702cases are concentrated in fort.14 parse-cursor lines. Filed as chore: adopt a ruff config and clear the 575 line-too-long / 82 semicolon-statement findings #262._vendor_admesh_truss.py. Vendored; left to track upstream.Issues filed
/tmppaths in benchmark and scene scripts (bandit B108), plus B310/B110 inpypi_publish.pyNo issues were closed.
Testing
pytest -k 'not block_o'before and after: 1488 passed, 79 skipped, 103 deselected, identical in both runs. Theblock_ofixture 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