xarray-spatial 0.9.8__tar.gz → 0.9.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.claude/commands/sweep-accuracy.md +3 -3
- xarray_spatial-0.9.9/.claude/commands/sweep-api-consistency.md +256 -0
- xarray_spatial-0.9.9/.claude/commands/sweep-metadata.md +297 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.claude/commands/sweep-performance.md +8 -6
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.claude/commands/sweep-security.md +4 -4
- xarray_spatial-0.9.9/.claude/commands/sweep-test-coverage.md +255 -0
- xarray_spatial-0.9.9/.claude/sweep-accuracy-state.csv +36 -0
- xarray_spatial-0.9.9/.claude/sweep-api-consistency-state.csv +1 -0
- xarray_spatial-0.9.9/.claude/sweep-metadata-state.csv +1 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.claude/sweep-performance-state.csv +4 -3
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.claude/sweep-security-state.csv +7 -7
- xarray_spatial-0.9.9/.claude/sweep-test-coverage-state.csv +1 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/CHANGELOG.md +65 -0
- {xarray_spatial-0.9.8/xarray_spatial.egg-info → xarray_spatial-0.9.9}/PKG-INFO +1 -1
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/RELEASE.md +1 -1
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9/xarray_spatial.egg-info}/PKG-INFO +1 -1
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xarray_spatial.egg-info/SOURCES.txt +16 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/_version.py +3 -3
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/bilateral.py +12 -4
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/convolution.py +7 -3
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/flood.py +21 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/__init__.py +305 -26
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/_geotags.py +94 -19
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/_gpu_decode.py +53 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/_reader.py +172 -38
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/_writer.py +100 -51
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_cog_http_concurrent.py +180 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/tests/test_edge_cases.py +5 -1
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_georef_edges.py +157 -0
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_geotags.py +255 -0
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_header.py +299 -0
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_metadata_round_trip_1484.py +418 -0
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_polish_1488.py +339 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/tests/test_predictor_multisample.py +50 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/tests/test_reader.py +68 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/tests/test_streaming_write.py +71 -0
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_writer_matrix.py +253 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/glcm.py +13 -5
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/gpu_rtx/mesh_utils.py +29 -3
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/fill_d8.py +6 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/flow_direction_d8.py +8 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/flow_direction_dinf.py +8 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/flow_direction_mfd.py +73 -2
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/flow_length_d8.py +8 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/flow_length_dinf.py +8 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/flow_length_mfd.py +8 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/flow_path_d8.py +90 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/flow_path_dinf.py +93 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/flow_path_mfd.py +89 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/hand_d8.py +5 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/hand_dinf.py +5 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/hand_mfd.py +48 -29
- xarray_spatial-0.9.9/xrspatial/hydro/sink_d8.py +513 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/snap_pour_point_d8.py +96 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/stream_link_d8.py +1 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/stream_link_dinf.py +3 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/stream_link_mfd.py +2 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/stream_order_d8.py +1 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/stream_order_dinf.py +3 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/stream_order_mfd.py +2 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_flow_direction_mfd.py +55 -2
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_flow_path_d8.py +79 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_flow_path_dinf.py +88 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_flow_path_mfd.py +90 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_hand_mfd.py +55 -0
- xarray_spatial-0.9.9/xrspatial/hydro/tests/test_sink_d8.py +415 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_snap_pour_point_d8.py +84 -0
- xarray_spatial-0.9.9/xrspatial/hydro/tests/test_validate_cellsize.py +113 -0
- xarray_spatial-0.9.9/xrspatial/hydro/tests/test_validate_scalar_params.py +124 -0
- xarray_spatial-0.9.9/xrspatial/hydro/tests/test_validate_secondary_args.py +137 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/twi_d8.py +8 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/watershed_d8.py +1 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/watershed_dinf.py +2 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/watershed_mfd.py +2 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/interpolate/_idw.py +50 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/interpolate/_spline.py +67 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/mahalanobis.py +12 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/mcda/combine.py +112 -2
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/mcda/sensitivity.py +6 -1
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/morphology.py +42 -38
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/pathfinding.py +25 -4
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/polygonize.py +10 -2
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/rasterize.py +9 -5
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/reproject/__init__.py +321 -73
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/reproject/_crs_utils.py +13 -2
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/reproject/_grid.py +84 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/reproject/_itrf.py +20 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/reproject/_vertical.py +18 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/resample.py +634 -111
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/sky_view_factor.py +73 -15
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/terrain.py +72 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_bilateral.py +46 -0
- xarray_spatial-0.9.9/xrspatial/tests/test_convolution.py +38 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_flood.py +68 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_glcm.py +46 -13
- xarray_spatial-0.9.9/xrspatial/tests/test_gpu_rtx_mesh.py +120 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_interpolation.py +142 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_mahalanobis.py +37 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_mcda.py +129 -7
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_morphology.py +122 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_multispectral.py +1 -1
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_pathfinding.py +52 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_polygonize.py +46 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_rasterize.py +85 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_reproject.py +1238 -1
- xarray_spatial-0.9.9/xrspatial/tests/test_resample.py +1275 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_sky_view_factor.py +123 -2
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_terrain.py +48 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_utils.py +83 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/utils.py +35 -6
- xarray_spatial-0.9.8/.claude/sweep-accuracy-state.csv +0 -19
- xarray_spatial-0.9.8/xrspatial/geotiff/tests/test_geotags.py +0 -109
- xarray_spatial-0.9.8/xrspatial/geotiff/tests/test_header.py +0 -123
- xarray_spatial-0.9.8/xrspatial/hydro/sink_d8.py +0 -276
- xarray_spatial-0.9.8/xrspatial/hydro/tests/test_sink_d8.py +0 -177
- xarray_spatial-0.9.8/xrspatial/tests/test_resample.py +0 -432
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.claude/commands/backend-parity.md +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.claude/commands/bench.md +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.claude/commands/dask-notebook.md +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.claude/commands/efficiency-audit.md +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.claude/commands/new-issues.md +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.claude/commands/release-major.md +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.claude/commands/release-minor.md +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.claude/commands/release-patch.md +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.claude/commands/review-pr.md +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.claude/commands/rockout.md +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.claude/commands/user-guide-notebook.md +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.claude/commands/validate.md +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.efficiency-audit-baseline.json +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.efficiency-audit-baseline.prev.json +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.gitattributes +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.github/ISSUE_TEMPLATE/feature-proposal.md +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.github/labeler.yml +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.github/pull_request_template.md +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.github/workflows/benchmarks.yml +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.github/workflows/labeler.yml +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.github/workflows/pypi-publish.yml +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.github/workflows/test.yml +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.gitignore +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/.readthedocs.yml +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/CODE_OF_CONDUCT.md +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/CONTRIBUTING.md +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/Citation-styles.md +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/LICENSE.txt +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/MANIFEST.in +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/README.md +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/codecov.yml +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/pyproject.toml +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/setup.cfg +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/setup.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xarray_spatial.egg-info/dependency_links.txt +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xarray_spatial.egg-info/entry_points.txt +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xarray_spatial.egg-info/not-zip-safe +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xarray_spatial.egg-info/requires.txt +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xarray_spatial.egg-info/top_level.txt +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/__init__.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/__main__.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/accessor.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/analytics.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/aspect.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/balanced_allocation.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/bump.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/classify.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/contour.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/corridor.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/cost_distance.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/curvature.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/dasymetric.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/dataset_support.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/datasets/__init__.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/datasets/sentinel-2/blue_band.nc +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/datasets/sentinel-2/green_band.nc +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/datasets/sentinel-2/nir_band.nc +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/datasets/sentinel-2/red_band.nc +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/datasets/sentinel-2/swir1_band.nc +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/datasets/sentinel-2/swir2_band.nc +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/diagnostics.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/diffusion.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/edge_detection.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/emerging_hotspots.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/erosion.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/experimental/__init__.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/experimental/min_observable_height.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/fire.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/focal.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geodesic.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/_compression.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/_dtypes.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/_header.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/_vrt.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/tests/__init__.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/tests/bench_vs_rioxarray.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/tests/conftest.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/tests/test_accessor_io.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/tests/test_accuracy_1081.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/tests/test_cog.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/tests/test_compression.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/tests/test_compression_level.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/tests/test_dtype_read.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/tests/test_features.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/tests/test_jpeg.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/tests/test_jpeg2000.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/tests/test_lerc.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/tests/test_lz4.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/tests/test_predictor_fp_write_1313.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/tests/test_security.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/tests/test_vrt_write.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/geotiff/tests/test_writer.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/gpu_rtx/__init__.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/gpu_rtx/_memory.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/gpu_rtx/cuda_utils.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/gpu_rtx/hillshade.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/gpu_rtx/viewshed.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hillshade.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/__init__.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/_boundary_store.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/basin_d8.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/flow_accumulation_d8.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/flow_accumulation_dinf.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/flow_accumulation_mfd.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/__init__.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/conftest.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_basin_d8.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_fill_d8.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_flow_accumulation_d8.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_flow_accumulation_dinf.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_flow_accumulation_mfd.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_flow_direction_d8.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_flow_direction_dinf.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_flow_length_d8.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_flow_length_dinf.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_flow_length_mfd.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_hand_d8.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_hand_dinf.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_stream_link_d8.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_stream_link_dinf.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_stream_link_mfd.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_stream_order_d8.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_stream_order_dinf.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_stream_order_mfd.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_twi_d8.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_watershed_d8.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_watershed_dinf.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/hydro/tests/test_watershed_mfd.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/interpolate/__init__.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/interpolate/_kriging.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/interpolate/_validation.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/kde.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/mcda/__init__.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/mcda/constrain.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/mcda/standardize.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/mcda/weights.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/multispectral.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/normalize.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/perlin.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/polygon_clip.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/preview.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/proximity.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/reproject/_datum_grids.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/reproject/_interpolate.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/reproject/_lite_crs.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/reproject/_merge.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/reproject/_projections.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/reproject/_projections_cuda.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/reproject/_transform.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/reproject/grids/at_bev_AT_GIS_GRID.tif +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/reproject/grids/au_icsm_A66_National_13_09_01.tif +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/reproject/grids/be_ign_bd72lb72_etrs89lb08.tif +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/reproject/grids/ch_swisstopo_CHENyx06_ETRS.tif +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/reproject/grids/de_adv_BETA2007.tif +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/reproject/grids/es_ign_SPED2ETV2.tif +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/reproject/grids/nl_nsgi_rdcorr2018.tif +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/reproject/grids/pt_dgt_D73_ETRS89_geo.tif +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/reproject/grids/uk_os_OSTN15_NTv2_OSGBtoETRS.tif +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/reproject/grids/us_nga_egm96_15.tif +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/reproject/grids/us_noaa_alaska.tif +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/reproject/grids/us_noaa_conus.tif +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/reproject/grids/us_noaa_hawaii.tif +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/reproject/grids/us_noaa_nadcon5_nad27_nad83_1986_conus.tif +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/reproject/grids/us_noaa_prvi.tif +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/sieve.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/slope.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/surface_distance.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/terrain_metrics.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/__init__.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/bench_reproject_vs_rioxarray.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/conftest.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/general_checks.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_accessor.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_analytics.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_aspect.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_balanced_allocation.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_bump.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_classify.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_contour.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_corridor.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_cost_distance.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_curvature.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_dask_cupy_gaps.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_dask_laziness.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_dasymetric.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_dataset_support.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_datasets.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_diagnostics.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_diffusion.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_edge_detection.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_emerging_hotspots.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_erosion.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_fire.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_focal.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_fused_overlap.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_geodesic_aspect.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_geodesic_slope.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_glcm_metric_order.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_gpu_rtx_memory.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_hillshade.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_hypsometric_integral.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_kde.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_lite_crs.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_min_observable_height.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_morphology_derived.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_multi_overlap.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_normalize.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_northness_eastness.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_perlin.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_polygon_clip.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_preview.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_proximity.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_rasterize_accuracy.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_rechunk_no_shuffle.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_sieve.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_sieve_gdal_parity.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_slope.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_surface_distance.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_terrain_metrics.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_validation.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_viewshed.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_visibility.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/tests/test_zonal.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/viewshed.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/visibility.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/worley.py +0 -0
- {xarray_spatial-0.9.8 → xarray_spatial-0.9.9}/xrspatial/zonal.py +0 -0
|
@@ -193,9 +193,9 @@ xrspatial/tests/general_checks.py for the cross-backend comparison helpers.
|
|
|
193
193
|
3. For each real issue found, assign a severity (CRITICAL/HIGH/MEDIUM/LOW)
|
|
194
194
|
and note the exact file and line number.
|
|
195
195
|
|
|
196
|
-
4. If any CRITICAL or
|
|
197
|
-
(GitHub issue, worktree branch, fix, tests, and PR).
|
|
198
|
-
For
|
|
196
|
+
4. If any CRITICAL, HIGH, or MEDIUM issue is found, run /rockout to fix it
|
|
197
|
+
end-to-end (GitHub issue, worktree branch, fix, tests, and PR).
|
|
198
|
+
For LOW issues, document them but do not fix.
|
|
199
199
|
|
|
200
200
|
5. After finishing (whether you found issues or not), update the inspection
|
|
201
201
|
state file .claude/sweep-accuracy-state.csv. The file is row-per-module
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
# API Consistency Sweep: Dispatch subagents to audit parameter naming and signature drift
|
|
2
|
+
|
|
3
|
+
Audit xrspatial modules for API consistency issues across analogous public
|
|
4
|
+
functions: parameter naming drift (`cellsize` vs `cell_size` vs `res`,
|
|
5
|
+
`agg` vs `raster` vs `data`), inconsistent return-type shapes, missing or
|
|
6
|
+
mismatched type hints, docstring/signature divergence. Cheap to find; makes
|
|
7
|
+
the library feel polished and predictable. Subagents fix CRITICAL, HIGH,
|
|
8
|
+
and MEDIUM findings via /rockout — but flag deprecation impact in the
|
|
9
|
+
issue since renames are breaking changes.
|
|
10
|
+
|
|
11
|
+
Optional arguments: $ARGUMENTS
|
|
12
|
+
(e.g. `--top 3`, `--exclude slope,aspect`, `--only-terrain`, `--reset-state`)
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Step 1 -- Gather module metadata via git
|
|
17
|
+
|
|
18
|
+
Enumerate candidate modules:
|
|
19
|
+
|
|
20
|
+
**Single-file modules:** Every `.py` file directly under `xrspatial/`, excluding
|
|
21
|
+
`__init__.py`, `_version.py`, `__main__.py`, `utils.py`, `accessor.py`,
|
|
22
|
+
`preview.py`, `dataset_support.py`, `diagnostics.py`, `analytics.py`.
|
|
23
|
+
|
|
24
|
+
**Subpackage modules:** `geotiff/`, `reproject/`, and `hydro/` directories under
|
|
25
|
+
`xrspatial/`. Treat each as a single audit unit.
|
|
26
|
+
|
|
27
|
+
For every module, collect:
|
|
28
|
+
|
|
29
|
+
| Field | How |
|
|
30
|
+
|-------|-----|
|
|
31
|
+
| **last_modified** | `git log -1 --format=%aI -- <path>` |
|
|
32
|
+
| **total_commits** | `git log --oneline -- <path> \| wc -l` |
|
|
33
|
+
| **loc** | `wc -l < <path>` |
|
|
34
|
+
| **public_funcs** | count of functions at module level (heuristic: `^def [a-z]`) |
|
|
35
|
+
|
|
36
|
+
Store results in memory -- do NOT write intermediate files.
|
|
37
|
+
|
|
38
|
+
## Step 2 -- Load inspection state
|
|
39
|
+
|
|
40
|
+
Read `.claude/sweep-api-consistency-state.csv`.
|
|
41
|
+
|
|
42
|
+
If it does not exist, treat every module as never-inspected. If
|
|
43
|
+
`$ARGUMENTS` contains `--reset-state`, delete the file first.
|
|
44
|
+
|
|
45
|
+
State file schema (one row per module):
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
module,last_inspected,issue,severity_max,categories_found,notes
|
|
49
|
+
slope,2026-05-01,1042,HIGH,1;3,"optional single-line notes"
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The file is registered with `merge=union` in `.gitattributes`.
|
|
53
|
+
|
|
54
|
+
## Step 3 -- Score each module
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
days_since_inspected = (today - last_inspected).days # 9999 if never
|
|
58
|
+
days_since_modified = (today - last_modified).days
|
|
59
|
+
|
|
60
|
+
score = (days_since_inspected * 3)
|
|
61
|
+
+ (public_funcs * 8)
|
|
62
|
+
+ (total_commits * 0.3)
|
|
63
|
+
- (days_since_modified * 0.1)
|
|
64
|
+
+ (loc * 0.03)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Rationale:
|
|
68
|
+
- Public function count weighted heavily — consistency issues are
|
|
69
|
+
cross-function comparisons, so more functions = more comparison surface
|
|
70
|
+
- Modules never inspected dominate
|
|
71
|
+
- Recently modified slightly deprioritized
|
|
72
|
+
|
|
73
|
+
## Step 4 -- Apply filters from $ARGUMENTS
|
|
74
|
+
|
|
75
|
+
Same filter set as other sweeps: `--top N`, `--exclude`, `--only-terrain`,
|
|
76
|
+
`--only-focal`, `--only-hydro`, `--only-io`, `--reset-state`.
|
|
77
|
+
|
|
78
|
+
## Step 5 -- Print the ranked table and launch subagents
|
|
79
|
+
|
|
80
|
+
### 5a. Print the ranked table
|
|
81
|
+
|
|
82
|
+
Print a markdown table showing ALL scored modules sorted by score descending.
|
|
83
|
+
|
|
84
|
+
### 5b. Launch subagents for the top N modules
|
|
85
|
+
|
|
86
|
+
For each of the top N modules (default 3), launch an Agent in parallel using
|
|
87
|
+
`isolation: "worktree"` and `mode: "auto"`. All N agents must be dispatched
|
|
88
|
+
in a single message so they run concurrently.
|
|
89
|
+
|
|
90
|
+
Each agent's prompt must be self-contained:
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
You are auditing the xrspatial module "{module}" for API consistency issues.
|
|
94
|
+
|
|
95
|
+
This module has {commits} commits and {loc} lines of code.
|
|
96
|
+
|
|
97
|
+
Read these files: {module_files}
|
|
98
|
+
|
|
99
|
+
Also read xrspatial/__init__.py to see what is publicly re-exported, and
|
|
100
|
+
xrspatial/utils.py for shared helpers.
|
|
101
|
+
|
|
102
|
+
For comparison, read 2-3 sibling modules (analogous functions). Examples:
|
|
103
|
+
- For aspect: also read slope.py and curvature.py
|
|
104
|
+
- For erosion: also read morphology.py
|
|
105
|
+
- For glcm: also read focal.py and convolution.py
|
|
106
|
+
The point is to compare parameter naming and return shapes against
|
|
107
|
+
modules with similar function families.
|
|
108
|
+
|
|
109
|
+
**Your task:**
|
|
110
|
+
|
|
111
|
+
1. Read all listed files thoroughly. For each public function, build a
|
|
112
|
+
small mental table of (function name, signature, return type).
|
|
113
|
+
|
|
114
|
+
2. Audit for these 5 API-consistency categories. Only flag issues ACTUALLY
|
|
115
|
+
present.
|
|
116
|
+
|
|
117
|
+
**Cat 1 — Parameter naming drift**
|
|
118
|
+
- HIGH: same concept named differently across analogous public
|
|
119
|
+
functions in this module or in sibling modules. Common offenders:
|
|
120
|
+
`cellsize` vs `cell_size` vs `res` vs `resolution`
|
|
121
|
+
`agg` vs `raster` vs `data` vs `array`
|
|
122
|
+
`x` vs `xs` vs `x_coords`
|
|
123
|
+
`nodata` vs `_FillValue` vs `nodata_value`
|
|
124
|
+
`cmap` vs `color_map` vs `colormap`
|
|
125
|
+
`kernel` vs `weights` vs `mask`
|
|
126
|
+
- MEDIUM: same concept named consistently inside this module but
|
|
127
|
+
different from sibling modules
|
|
128
|
+
- MEDIUM: positional-vs-keyword convention drift (sibling functions
|
|
129
|
+
accept the same arg, one as positional, one as keyword-only)
|
|
130
|
+
Severity: HIGH if both names exist in the public API at the same time
|
|
131
|
+
(real user-facing inconsistency); MEDIUM otherwise
|
|
132
|
+
|
|
133
|
+
**Cat 2 — Return shape drift**
|
|
134
|
+
- HIGH: analogous functions return different types (one returns
|
|
135
|
+
DataArray, sibling returns Dataset for the same conceptual op)
|
|
136
|
+
- HIGH: tuple-return vs single-return drift (one function returns
|
|
137
|
+
`(slope, aspect)`, analog returns `slope` only — caller cannot
|
|
138
|
+
interchange)
|
|
139
|
+
- MEDIUM: result coord/attr conventions differ (one function emits
|
|
140
|
+
`attrs['units']`, sibling does not)
|
|
141
|
+
- MEDIUM: in-place vs returned-copy semantics drift
|
|
142
|
+
Severity: HIGH if it breaks substitutability between sibling functions
|
|
143
|
+
|
|
144
|
+
**Cat 3 — Type hints and docstrings**
|
|
145
|
+
- MEDIUM: missing type hints on a public function while sibling
|
|
146
|
+
functions in this module have them
|
|
147
|
+
- MEDIUM: type hint says `xr.DataArray` but the docstring example
|
|
148
|
+
passes a numpy array (or vice versa) — docs/types disagree
|
|
149
|
+
- MEDIUM: docstring lists a parameter that does not exist in the
|
|
150
|
+
signature (or omits one that does)
|
|
151
|
+
- MEDIUM: docstring says "Returns: DataArray" but the function returns
|
|
152
|
+
a tuple
|
|
153
|
+
- LOW: docstring style drift (numpy-style vs google-style mix)
|
|
154
|
+
Severity: MEDIUM (these are documentation bugs that mislead users)
|
|
155
|
+
|
|
156
|
+
**Cat 4 — Default value inconsistency**
|
|
157
|
+
- HIGH: same parameter has different defaults in analogous functions
|
|
158
|
+
(e.g. `kernel_size=3` in one function, `kernel_size=5` in sibling,
|
|
159
|
+
no documented reason)
|
|
160
|
+
- MEDIUM: default uses a mutable type (`def f(x=[])`) — Python anti-pattern
|
|
161
|
+
- MEDIUM: default `None` plus internal substitution where a literal
|
|
162
|
+
default would be clearer and equally correct
|
|
163
|
+
Severity: HIGH if user-surprise is likely (silent behavior change
|
|
164
|
+
when switching between sibling functions)
|
|
165
|
+
|
|
166
|
+
**Cat 5 — Public API surface drift**
|
|
167
|
+
- HIGH: function is called by tests and notebooks but is not in
|
|
168
|
+
`xrspatial/__init__.py` or in the module's `__all__` (orphan API)
|
|
169
|
+
- HIGH: function in `__all__` but undocumented in the docstring
|
|
170
|
+
- MEDIUM: deprecated alias still exported with no `DeprecationWarning`
|
|
171
|
+
- MEDIUM: private-looking name (`_foo`) but is referenced in tests as
|
|
172
|
+
if public
|
|
173
|
+
- LOW: `from .module import *` patterns that bring inconsistent
|
|
174
|
+
symbols into the public namespace
|
|
175
|
+
Severity: HIGH for orphan APIs (users find them, depend on them, then
|
|
176
|
+
break when they vanish)
|
|
177
|
+
|
|
178
|
+
3. For each real issue, assign severity + file:line.
|
|
179
|
+
|
|
180
|
+
4. If any CRITICAL, HIGH, or MEDIUM issue is found, run /rockout to fix it.
|
|
181
|
+
IMPORTANT: parameter renames are breaking changes — for HIGH
|
|
182
|
+
parameter-rename fixes, the rockout PR must add a deprecation
|
|
183
|
+
shim (accept both old and new names; emit DeprecationWarning on the
|
|
184
|
+
old name; update docs). Document this in the issue body. For LOW
|
|
185
|
+
issues, document but do not fix.
|
|
186
|
+
|
|
187
|
+
5. Update .claude/sweep-api-consistency-state.csv using csv.DictReader/Writer:
|
|
188
|
+
|
|
189
|
+
```python
|
|
190
|
+
import csv
|
|
191
|
+
from pathlib import Path
|
|
192
|
+
|
|
193
|
+
path = Path(".claude/sweep-api-consistency-state.csv")
|
|
194
|
+
header = ["module", "last_inspected", "issue", "severity_max",
|
|
195
|
+
"categories_found", "notes"]
|
|
196
|
+
|
|
197
|
+
rows = {}
|
|
198
|
+
if path.exists():
|
|
199
|
+
with path.open() as f:
|
|
200
|
+
for r in csv.DictReader(f):
|
|
201
|
+
rows[r["module"]] = r
|
|
202
|
+
|
|
203
|
+
rows["{module}"] = {
|
|
204
|
+
"module": "{module}",
|
|
205
|
+
"last_inspected": "<today's ISO date>",
|
|
206
|
+
"issue": "<issue number or empty>",
|
|
207
|
+
"severity_max": "<HIGH|MEDIUM|LOW or empty>",
|
|
208
|
+
"categories_found": "<semicolon-joined ints or empty>",
|
|
209
|
+
"notes": "<single-line notes or empty>",
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
with path.open("w", newline="") as f:
|
|
213
|
+
w = csv.DictWriter(f, fieldnames=header, quoting=csv.QUOTE_MINIMAL)
|
|
214
|
+
w.writeheader()
|
|
215
|
+
for m in sorted(rows):
|
|
216
|
+
w.writerow(rows[m])
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Then `git add` and commit.
|
|
220
|
+
|
|
221
|
+
Important:
|
|
222
|
+
- Only flag real consistency issues. The lib has 40+ modules — do not
|
|
223
|
+
list every minor naming difference; focus on user-facing surprise.
|
|
224
|
+
- Compare against 2-3 sibling modules. Cross-cutting concerns (e.g.
|
|
225
|
+
cellsize naming convention) often span the whole library; if a rename
|
|
226
|
+
is safe in one module but breaks 20 others, surface that as a notes
|
|
227
|
+
comment, do not file a per-module issue.
|
|
228
|
+
- For the hydro subpackage: pick one variant (d8) and check whether
|
|
229
|
+
dinf/mfd siblings agree.
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### 5c. Print a status line
|
|
233
|
+
|
|
234
|
+
After dispatching, print:
|
|
235
|
+
|
|
236
|
+
```
|
|
237
|
+
Launched {N} API consistency audit agents: {module1}, {module2}, {module3}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Step 6 -- State updates
|
|
241
|
+
|
|
242
|
+
To reset: `/sweep-api-consistency --reset-state`
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## General Rules
|
|
247
|
+
|
|
248
|
+
- Do NOT modify any source files directly. Subagents handle fixes.
|
|
249
|
+
- Keep the output concise.
|
|
250
|
+
- If $ARGUMENTS is empty, use defaults: top 3, no category filter, no
|
|
251
|
+
exclusions.
|
|
252
|
+
- State file (`.claude/sweep-api-consistency-state.csv`) is tracked in
|
|
253
|
+
git with `merge=union`.
|
|
254
|
+
- Renames are breaking. The fix path is a deprecation shim, not a
|
|
255
|
+
hard rename, unless the function has a clearly orphan/private status.
|
|
256
|
+
- False positives are worse than missed issues.
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
# Metadata Propagation Sweep: Dispatch subagents to audit modules for metadata preservation
|
|
2
|
+
|
|
3
|
+
Audit xrspatial modules for metadata propagation bugs: attrs (especially
|
|
4
|
+
`res`, `crs`, `transform`, `nodatavals`, `_FillValue`), coords (x/y values
|
|
5
|
+
and dims), and dim names. Spatial libs lose CRS/transform silently and the
|
|
6
|
+
result looks correct but is wrong. The sky_view_factor cellsize bug
|
|
7
|
+
(#1407) was exactly this class of issue. Subagents fix CRITICAL, HIGH, and
|
|
8
|
+
MEDIUM findings via /rockout.
|
|
9
|
+
|
|
10
|
+
Optional arguments: $ARGUMENTS
|
|
11
|
+
(e.g. `--top 3`, `--exclude slope,aspect`, `--only-terrain`, `--reset-state`)
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Step 1 -- Gather module metadata via git
|
|
16
|
+
|
|
17
|
+
Enumerate candidate modules:
|
|
18
|
+
|
|
19
|
+
**Single-file modules:** Every `.py` file directly under `xrspatial/`, excluding
|
|
20
|
+
`__init__.py`, `_version.py`, `__main__.py`, `utils.py`, `accessor.py`,
|
|
21
|
+
`preview.py`, `dataset_support.py`, `diagnostics.py`, `analytics.py`.
|
|
22
|
+
|
|
23
|
+
**Subpackage modules:** `geotiff/`, `reproject/`, and `hydro/` directories under
|
|
24
|
+
`xrspatial/`. Treat each as a single audit unit. List all `.py` files within
|
|
25
|
+
each (excluding `__init__.py`).
|
|
26
|
+
|
|
27
|
+
For every module, collect:
|
|
28
|
+
|
|
29
|
+
| Field | How |
|
|
30
|
+
|-------|-----|
|
|
31
|
+
| **last_modified** | `git log -1 --format=%aI -- <path>` (for subpackages, most recent file) |
|
|
32
|
+
| **total_commits** | `git log --oneline -- <path> \| wc -l` |
|
|
33
|
+
| **loc** | `wc -l < <path>` (for subpackages, sum all files) |
|
|
34
|
+
| **public_funcs** | count of functions defined at module level (heuristic: `^def [a-z]` not starting with `_`) |
|
|
35
|
+
|
|
36
|
+
Store results in memory -- do NOT write intermediate files.
|
|
37
|
+
|
|
38
|
+
## Step 2 -- Load inspection state
|
|
39
|
+
|
|
40
|
+
Read `.claude/sweep-metadata-state.csv`.
|
|
41
|
+
|
|
42
|
+
If it does not exist, treat every module as never-inspected.
|
|
43
|
+
|
|
44
|
+
If `$ARGUMENTS` contains `--reset-state`, delete the file and treat
|
|
45
|
+
everything as never-inspected.
|
|
46
|
+
|
|
47
|
+
State file schema (one row per module):
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
module,last_inspected,issue,severity_max,categories_found,notes
|
|
51
|
+
slope,2026-05-01,1042,HIGH,1;3,"optional single-line notes"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
- `categories_found` is a semicolon-separated integer list (empty when null).
|
|
55
|
+
- `notes` is CSV-quoted; newlines must be flattened to spaces on write so
|
|
56
|
+
every module stays exactly one line.
|
|
57
|
+
|
|
58
|
+
The file is registered with `merge=union` in `.gitattributes`, so two
|
|
59
|
+
parallel sweeps touching different modules auto-merge without conflict.
|
|
60
|
+
A transient duplicate-row state can occur after a merge if both branches
|
|
61
|
+
modified the same module; the read-update-write cycle in step 5 keys rows
|
|
62
|
+
by `module` and last-write-wins, so the next write cleans up.
|
|
63
|
+
|
|
64
|
+
## Step 3 -- Score each module
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
days_since_inspected = (today - last_inspected).days # 9999 if never
|
|
68
|
+
days_since_modified = (today - last_modified).days
|
|
69
|
+
|
|
70
|
+
score = (days_since_inspected * 3)
|
|
71
|
+
+ (public_funcs * 5)
|
|
72
|
+
+ (total_commits * 0.3)
|
|
73
|
+
- (days_since_modified * 0.2)
|
|
74
|
+
+ (loc * 0.05)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Rationale:
|
|
78
|
+
- Modules never inspected dominate (9999 * 3)
|
|
79
|
+
- More public functions = more API surface that could lose metadata
|
|
80
|
+
- More commits = more refactor risk for metadata propagation
|
|
81
|
+
- Recently modified modules slightly deprioritized
|
|
82
|
+
- Larger files have more surface area
|
|
83
|
+
|
|
84
|
+
## Step 4 -- Apply filters from $ARGUMENTS
|
|
85
|
+
|
|
86
|
+
- `--top N` -- only audit the top N modules (default: 3)
|
|
87
|
+
- `--exclude mod1,mod2` -- remove named modules from the list
|
|
88
|
+
- `--only-terrain` -- restrict to: slope, aspect, curvature, terrain,
|
|
89
|
+
terrain_metrics, hillshade, sky_view_factor
|
|
90
|
+
- `--only-focal` -- restrict to: focal, convolution, morphology, bilateral,
|
|
91
|
+
edge_detection, glcm
|
|
92
|
+
- `--only-hydro` -- restrict to: flood, cost_distance, geodesic,
|
|
93
|
+
surface_distance, viewshed, erosion, diffusion, hydro (subpackage)
|
|
94
|
+
- `--only-io` -- restrict to: geotiff, reproject, rasterize, polygonize
|
|
95
|
+
|
|
96
|
+
## Step 5 -- Print the ranked table and launch subagents
|
|
97
|
+
|
|
98
|
+
### 5a. Print the ranked table
|
|
99
|
+
|
|
100
|
+
Print a markdown table showing ALL scored modules sorted by score descending.
|
|
101
|
+
|
|
102
|
+
### 5b. Launch subagents for the top N modules
|
|
103
|
+
|
|
104
|
+
For each of the top N modules (default 3), launch an Agent in parallel using
|
|
105
|
+
`isolation: "worktree"` and `mode: "auto"`. All N agents must be dispatched
|
|
106
|
+
in a single message so they run concurrently.
|
|
107
|
+
|
|
108
|
+
Each agent's prompt must be self-contained and follow this template (adapt
|
|
109
|
+
the module name, paths, and metadata):
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
You are auditing the xrspatial module "{module}" for metadata propagation issues.
|
|
113
|
+
|
|
114
|
+
This module has {commits} commits and {loc} lines of code.
|
|
115
|
+
|
|
116
|
+
Read these files: {module_files}
|
|
117
|
+
|
|
118
|
+
Also read xrspatial/utils.py to understand:
|
|
119
|
+
- _validate_raster() behavior — what does it accept/reject?
|
|
120
|
+
- get_dataarray_resolution() — what attrs does it pull from?
|
|
121
|
+
- ngjit / ArrayTypeFunctionMapping dispatch helpers
|
|
122
|
+
|
|
123
|
+
Read xrspatial/tests/general_checks.py for cross-backend test helpers.
|
|
124
|
+
|
|
125
|
+
**Your task:**
|
|
126
|
+
|
|
127
|
+
1. Read all listed files thoroughly, including the matching test file(s)
|
|
128
|
+
under xrspatial/tests/ so you understand expected behavior. Pay
|
|
129
|
+
particular attention to whether tests assert on attrs/coords/dims of
|
|
130
|
+
the returned DataArray.
|
|
131
|
+
|
|
132
|
+
2. Audit for these 5 metadata-propagation categories. Only flag issues
|
|
133
|
+
ACTUALLY present in the code.
|
|
134
|
+
|
|
135
|
+
**Cat 1 — attrs preservation**
|
|
136
|
+
- HIGH: result DataArray has empty attrs even though input had attrs
|
|
137
|
+
(`return xr.DataArray(out_data, dims=...)` instead of `dims=in.dims,
|
|
138
|
+
attrs=in.attrs`)
|
|
139
|
+
- HIGH: function silently drops `res`, `crs`, `transform`, or
|
|
140
|
+
`nodatavals` from input attrs
|
|
141
|
+
- HIGH: function reads `attrs['res']` for math but does not re-emit it
|
|
142
|
+
on output (downstream callers see no res, recompute from coords,
|
|
143
|
+
get different answer)
|
|
144
|
+
- MEDIUM: function copies attrs but adds an inferred attr that
|
|
145
|
+
overwrites a user-provided value (e.g. always sets `nodatavals` to
|
|
146
|
+
`[np.nan]` even if input had `[-9999]`)
|
|
147
|
+
- MEDIUM: attrs propagated for the eager path but lost on the dask path
|
|
148
|
+
(or vice versa)
|
|
149
|
+
Severity: HIGH if downstream spatial computation is affected (slope of
|
|
150
|
+
a no-CRS raster gives wrong cell-size answers); MEDIUM otherwise
|
|
151
|
+
|
|
152
|
+
**Cat 2 — coords preservation**
|
|
153
|
+
- HIGH: result has integer-index coords (0,1,2,...) when input had
|
|
154
|
+
georeferenced coords (lon/lat or projected x/y)
|
|
155
|
+
- HIGH: coordinate values are stale by half-a-pixel after resampling
|
|
156
|
+
(centre vs corner convention drift)
|
|
157
|
+
- HIGH: coord dtype changes (float64 → float32) silently between input
|
|
158
|
+
and output
|
|
159
|
+
- MEDIUM: extra coords from input (e.g. `time`, `band`) are dropped on
|
|
160
|
+
output even though they should pass through
|
|
161
|
+
- MEDIUM: coord names renamed without the function documenting why
|
|
162
|
+
(`x` → `lon`, `y` → `lat`, etc.)
|
|
163
|
+
Severity: HIGH if downstream coord-based math (clipping, interp) breaks
|
|
164
|
+
|
|
165
|
+
**Cat 3 — dim names and order**
|
|
166
|
+
- HIGH: output dim order differs from input dim order without
|
|
167
|
+
documentation (e.g. input `(y, x)`, output `(x, y)`)
|
|
168
|
+
- HIGH: output has fewer/more dims than input without the function
|
|
169
|
+
docstring saying so (e.g. reduces over `y` but doesn't reflect that
|
|
170
|
+
in the dim list)
|
|
171
|
+
- MEDIUM: function assumes hardcoded dim names (`y`, `x`) and silently
|
|
172
|
+
mis-aligns when input uses (`lat`, `lon`) or (`row`, `col`)
|
|
173
|
+
- MEDIUM: dask backend preserves dims, numpy backend does not (or vice
|
|
174
|
+
versa)
|
|
175
|
+
Severity: HIGH if it breaks chained xarray operations
|
|
176
|
+
|
|
177
|
+
**Cat 4 — dtype and nodata semantics**
|
|
178
|
+
- HIGH: function reads `attrs['nodatavals']` for input mask but does
|
|
179
|
+
not propagate it to output (so a chained call sees the old nodata,
|
|
180
|
+
possibly wrong)
|
|
181
|
+
- HIGH: output dtype hardcoded to float64 even when input was uint8
|
|
182
|
+
(memory blowup; downstream stats wrong)
|
|
183
|
+
- MEDIUM: NaN used as the nodata sentinel internally but output dtype
|
|
184
|
+
is integer (NaN cannot represent — silent conversion to MIN_INT or 0)
|
|
185
|
+
- MEDIUM: `_FillValue` attr present on input but not on output
|
|
186
|
+
Severity: HIGH if nodata mask is silently flipped or dtype change
|
|
187
|
+
causes wrong arithmetic downstream
|
|
188
|
+
|
|
189
|
+
**Cat 5 — backend-inconsistent metadata**
|
|
190
|
+
- HIGH: numpy and cupy backends emit attrs differently (e.g. numpy
|
|
191
|
+
keeps `crs`, cupy drops it, or numpy emits `_FillValue`, cupy emits
|
|
192
|
+
`nodatavals`)
|
|
193
|
+
- HIGH: dask path's metadata is computed from chunk-local stats not
|
|
194
|
+
global stats (e.g. `attrs['min']` is per-chunk min, not global min)
|
|
195
|
+
- MEDIUM: only one of the four backends (numpy / cupy / dask+numpy /
|
|
196
|
+
dask+cupy) preserves attrs
|
|
197
|
+
- MEDIUM: result name (`.name`) inconsistent across backends
|
|
198
|
+
Severity: HIGH if a chained pipeline silently produces different
|
|
199
|
+
numbers depending on which backend is active
|
|
200
|
+
|
|
201
|
+
3. For each real issue found, assign a severity (CRITICAL/HIGH/MEDIUM/LOW)
|
|
202
|
+
and note the exact file and line number.
|
|
203
|
+
|
|
204
|
+
4. If any CRITICAL, HIGH, or MEDIUM issue is found, run /rockout to fix it
|
|
205
|
+
end-to-end (GitHub issue, worktree branch, fix, tests, and PR). For
|
|
206
|
+
LOW issues, document them but do not fix.
|
|
207
|
+
|
|
208
|
+
5. After finishing (whether you found issues or not), update the inspection
|
|
209
|
+
state file .claude/sweep-metadata-state.csv. Header:
|
|
210
|
+
|
|
211
|
+
`module,last_inspected,issue,severity_max,categories_found,notes`
|
|
212
|
+
|
|
213
|
+
Use this Python pattern (do NOT hand-edit the file):
|
|
214
|
+
|
|
215
|
+
```python
|
|
216
|
+
import csv
|
|
217
|
+
from pathlib import Path
|
|
218
|
+
|
|
219
|
+
path = Path(".claude/sweep-metadata-state.csv")
|
|
220
|
+
header = ["module", "last_inspected", "issue", "severity_max",
|
|
221
|
+
"categories_found", "notes"]
|
|
222
|
+
|
|
223
|
+
rows = {}
|
|
224
|
+
if path.exists():
|
|
225
|
+
with path.open() as f:
|
|
226
|
+
for r in csv.DictReader(f):
|
|
227
|
+
rows[r["module"]] = r
|
|
228
|
+
|
|
229
|
+
rows["{module}"] = {
|
|
230
|
+
"module": "{module}",
|
|
231
|
+
"last_inspected": "<today's ISO date, e.g. 2026-05-03>",
|
|
232
|
+
"issue": "<issue number from rockout, or empty>",
|
|
233
|
+
"severity_max": "<HIGH|MEDIUM|LOW, or empty>",
|
|
234
|
+
"categories_found": "<semicolon-joined ints, e.g. 1;3, or empty>",
|
|
235
|
+
"notes": "<single-line notes (replace any newlines with spaces), or empty>",
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
with path.open("w", newline="") as f:
|
|
239
|
+
w = csv.DictWriter(f, fieldnames=header, quoting=csv.QUOTE_MINIMAL)
|
|
240
|
+
w.writeheader()
|
|
241
|
+
for m in sorted(rows):
|
|
242
|
+
w.writerow(rows[m])
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Use empty strings (not `null`) for missing values.
|
|
246
|
+
|
|
247
|
+
Then `git add .claude/sweep-metadata-state.csv` and commit it to the
|
|
248
|
+
worktree branch so the state update lands in the PR.
|
|
249
|
+
|
|
250
|
+
Important:
|
|
251
|
+
- Only flag real metadata propagation issues. False positives waste time.
|
|
252
|
+
- Read the tests for this module before flagging — the test may codify
|
|
253
|
+
the current behavior intentionally (e.g. an aggregation that genuinely
|
|
254
|
+
drops a dim).
|
|
255
|
+
- Verify by reading the function end-to-end: does the input DataArray's
|
|
256
|
+
attrs/coords/dims get propagated to the returned DataArray?
|
|
257
|
+
- For ALL backends, not just numpy. Check numpy / cupy / dask+numpy /
|
|
258
|
+
dask+cupy paths.
|
|
259
|
+
- Do NOT flag the use of numba @jit itself.
|
|
260
|
+
- For the hydro subpackage: focus on one representative variant (d8) in
|
|
261
|
+
detail, then note which dinf/mfd files share the same pattern.
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### 5c. Print a status line
|
|
265
|
+
|
|
266
|
+
After dispatching, print:
|
|
267
|
+
|
|
268
|
+
```
|
|
269
|
+
Launched {N} metadata propagation audit agents: {module1}, {module2}, {module3}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## Step 6 -- State updates
|
|
273
|
+
|
|
274
|
+
State is updated by the subagents themselves. After completion, verify with:
|
|
275
|
+
|
|
276
|
+
```
|
|
277
|
+
column -t -s, .claude/sweep-metadata-state.csv | less
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
To reset all tracking: `/sweep-metadata --reset-state`
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
## General Rules
|
|
285
|
+
|
|
286
|
+
- Do NOT modify any source files directly. Subagents handle fixes via /rockout.
|
|
287
|
+
- Keep the parent output concise — the ranked table and dispatch line are
|
|
288
|
+
the deliverables.
|
|
289
|
+
- If $ARGUMENTS is empty, use defaults: top 3, no category filter, no
|
|
290
|
+
exclusions.
|
|
291
|
+
- State file (`.claude/sweep-metadata-state.csv`) is tracked in git, with
|
|
292
|
+
`merge=union` set in `.gitattributes` so parallel sweeps touching
|
|
293
|
+
different modules auto-merge.
|
|
294
|
+
- For subpackage modules (geotiff, reproject, hydro), the subagent should
|
|
295
|
+
read ALL `.py` files in the subpackage directory, not just `__init__.py`.
|
|
296
|
+
- Only flag patterns that are ACTUALLY present in the code.
|
|
297
|
+
- False positives are worse than missed issues. When in doubt, skip.
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# Performance Sweep: Dispatch subagents to audit and fix performance issues
|
|
2
2
|
|
|
3
3
|
Audit xrspatial modules for performance bottlenecks, OOM risk under 30TB dask
|
|
4
|
-
workloads, and backend-specific anti-patterns. Subagents fix HIGH
|
|
5
|
-
findings via /rockout in the same agent that did the audit,
|
|
4
|
+
workloads, and backend-specific anti-patterns. Subagents fix HIGH and
|
|
5
|
+
MEDIUM-severity findings via /rockout in the same agent that did the audit,
|
|
6
|
+
in parallel.
|
|
6
7
|
|
|
7
8
|
Optional arguments: $ARGUMENTS
|
|
8
9
|
(e.g. `--top 5`, `--exclude slope,aspect`, `--only-io`, `--reset-state`)
|
|
@@ -214,10 +215,11 @@ xrspatial/tests/general_checks.py for cross-backend test helpers.
|
|
|
214
215
|
4. For each real issue found, assign a severity (CRITICAL/HIGH/MEDIUM/LOW)
|
|
215
216
|
and note the exact file and line number.
|
|
216
217
|
|
|
217
|
-
5. If any CRITICAL or
|
|
218
|
-
(GitHub issue, worktree branch, fix, tests, and PR). Include
|
|
219
|
-
verdict, bottleneck classification, and affected backends in the
|
|
220
|
-
prompt so it has full performance context.
|
|
218
|
+
5. If any CRITICAL, HIGH, or MEDIUM issue is found, run /rockout to fix it
|
|
219
|
+
end-to-end (GitHub issue, worktree branch, fix, tests, and PR). Include
|
|
220
|
+
the OOM verdict, bottleneck classification, and affected backends in the
|
|
221
|
+
rockout prompt so it has full performance context. For LOW issues,
|
|
222
|
+
document them but do not fix.
|
|
221
223
|
|
|
222
224
|
Skip step 5 entirely if `--no-fix` was passed to the parent sweep.
|
|
223
225
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Audit xrspatial modules for security issues specific to numeric/GPU raster
|
|
4
4
|
libraries: unbounded allocations, integer overflow, NaN logic bombs, GPU
|
|
5
5
|
kernel bounds, file path injection, and dtype confusion. Subagents fix
|
|
6
|
-
CRITICAL
|
|
6
|
+
CRITICAL, HIGH, and MEDIUM severity issues via /rockout.
|
|
7
7
|
|
|
8
8
|
Optional arguments: $ARGUMENTS
|
|
9
9
|
(e.g. `--top 3`, `--exclude slope,aspect`, `--only-io`, `--reset-state`)
|
|
@@ -192,9 +192,9 @@ Also read xrspatial/utils.py to understand _validate_raster() behavior.
|
|
|
192
192
|
3. For each real issue found, assign a severity (CRITICAL/HIGH/MEDIUM/LOW)
|
|
193
193
|
and note the exact file and line number.
|
|
194
194
|
|
|
195
|
-
4. If any CRITICAL or
|
|
196
|
-
(GitHub issue, worktree branch, fix, tests, and PR).
|
|
197
|
-
For
|
|
195
|
+
4. If any CRITICAL, HIGH, or MEDIUM issue is found, run /rockout to fix it
|
|
196
|
+
end-to-end (GitHub issue, worktree branch, fix, tests, and PR).
|
|
197
|
+
For LOW issues, document them but do not fix.
|
|
198
198
|
|
|
199
199
|
5. After finishing (whether you found issues or not), update the inspection
|
|
200
200
|
state file .claude/sweep-security-state.csv. The file is row-per-module
|