xarray-spatial 0.9.9__tar.gz → 0.10.0__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.10.0/.claude/commands/deep-sweep.md +432 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.claude/commands/release-patch.md +38 -4
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.claude/commands/review-pr.md +65 -2
- xarray_spatial-0.10.0/.claude/commands/rockout.md +374 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.claude/commands/sweep-accuracy.md +33 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.claude/commands/sweep-api-consistency.md +29 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.claude/commands/sweep-metadata.md +31 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.claude/commands/sweep-performance.md +33 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.claude/commands/sweep-security.md +34 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.claude/commands/sweep-test-coverage.md +32 -0
- xarray_spatial-0.10.0/.claude/sweep-accuracy-state.csv +36 -0
- xarray_spatial-0.10.0/.claude/sweep-api-consistency-state.csv +5 -0
- xarray_spatial-0.10.0/.claude/sweep-metadata-state.csv +5 -0
- xarray_spatial-0.10.0/.claude/sweep-performance-state.csv +47 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.claude/sweep-security-state.csv +4 -6
- xarray_spatial-0.10.0/.claude/sweep-style-state.csv +2 -0
- xarray_spatial-0.10.0/.claude/sweep-test-coverage-state.csv +7 -0
- xarray_spatial-0.10.0/.github/ISSUE_TEMPLATE/new-contributor.md +64 -0
- xarray_spatial-0.10.0/.github/workflows/copilot-review.yml +30 -0
- xarray_spatial-0.10.0/.github/workflows/test-cog-validator.yml +104 -0
- xarray_spatial-0.10.0/.github/workflows/test-geotiff-corpus.yml +84 -0
- xarray_spatial-0.10.0/.github/workflows/test.yml +52 -0
- xarray_spatial-0.10.0/.github/workflows/welcome-contributor.yml +64 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.gitignore +2 -0
- xarray_spatial-0.10.0/AI_POLICY.md +312 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/CHANGELOG.md +70 -0
- xarray_spatial-0.10.0/CONTRIBUTING.md +87 -0
- {xarray_spatial-0.9.9/xarray_spatial.egg-info → xarray_spatial-0.10.0}/PKG-INFO +210 -234
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/README.md +197 -230
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/setup.cfg +15 -3
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0/xarray_spatial.egg-info}/PKG-INFO +210 -234
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xarray_spatial.egg-info/SOURCES.txt +167 -24
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xarray_spatial.egg-info/requires.txt +15 -3
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/_version.py +3 -3
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/accessor.py +71 -6
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/balanced_allocation.py +1 -1
- xarray_spatial-0.10.0/xrspatial/geotiff/__init__.py +903 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_attrs.py +1744 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_backends/__init__.py +8 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_backends/_gpu_helpers.py +333 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_backends/dask.py +759 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_backends/gpu.py +1706 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_backends/vrt.py +1298 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_cog_http.py +1039 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_compression.py +1887 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_coords.py +811 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_crs.py +321 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_decode.py +915 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_dtypes.py +279 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_encode.py +674 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_errors.py +290 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_geotags.py +1704 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/geotiff/_gpu_decode.py +1015 -152
- xarray_spatial-0.10.0/xrspatial/geotiff/_header.py +924 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_layout.py +205 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_nodata.py +368 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_overview.py +505 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_overview_kernels.py +268 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_reader.py +429 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_runtime.py +150 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_safe_xml.py +108 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_sidecar.py +436 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_sources.py +1779 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_validation.py +1511 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_vrt.py +2244 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_vrt_validation.py +664 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_write_layout.py +711 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_writer.py +1320 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_writers/__init__.py +7 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_writers/eager.py +1393 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_writers/gpu.py +725 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/_writers/vrt.py +227 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/_helpers/__init__.py +8 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/_helpers/markers.py +67 -0
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/conftest.py → xarray_spatial-0.10.0/xrspatial/geotiff/tests/_helpers/tiff_builders.py +7 -36
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/_helpers/tiff_surgery.py +75 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/attrs/test_contract.py +968 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/geotiff/tests/bench_vs_rioxarray.py +9 -5
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/conftest.py +60 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/README.md +85 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/__init__.py +12 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/_marks.py +61 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/_oracle.py +709 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/cog_internal_overview_uint16.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/compression_deflate_predictor2_uint16.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/compression_deflate_predictor3_float32.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/compression_jpeg_uint8_ycbcr.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/compression_lerc_float32.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/compression_lzw_predictor2_int16.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/compression_none_uint8.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/crs_citation_only.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/crs_epsg_3857.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/crs_wkt_utm10n.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_float32.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_float64.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_int16.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_int32.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_int8.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_uint16.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_uint32.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_uint8.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/extra_tags_uint16.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/gdal_metadata_namespaced_uint16.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/nodata_int_sentinel_uint16.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/nodata_miniswhite_uint8.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/nodata_nan_float32.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/overview_external_ovr_uint16.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/overview_external_ovr_uint16.tif.ovr +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/overview_internal_uint16.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/planar_separate_uint8_rgb.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/sparse_tiled_uint16.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/stripped_be_uint16.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/stripped_le_uint16.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/tiled_be_uint16.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/fixtures/tiled_le_uint16.tif +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/generate.py +880 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/manifest.yaml +740 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/test_compression.py +247 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/test_corpus_determinism.py +419 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/test_dask_gpu.py +242 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/test_dask_numpy.py +233 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/test_dtype_variants.py +187 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/test_eager_numpy.py +204 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/test_fsspec.py +276 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/test_gpu.py +245 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/test_http.py +219 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/test_layout_endian.py +122 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/test_manifest.py +176 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/test_metadata_tags.py +270 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/test_nodata_sentinels.py +192 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/test_oracle.py +1432 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/test_overview_cog.py +281 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/golden_corpus/test_vrt.py +149 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/gpu/__init__.py +1 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/gpu/test_codec.py +1890 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/gpu/test_kernels_and_kwargs.py +3131 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/gpu/test_reader.py +1551 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/gpu/test_writer.py +2122 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/integration/test_dask_pipeline.py +1034 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/integration/test_gpu_pipeline.py +188 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/integration/test_http_sources.py +6311 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/integration/test_sidecar.py +1865 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/parity/__init__.py +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/parity/test_backend_matrix.py +2806 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/parity/test_finalization.py +1102 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/parity/test_pixel_equality.py +660 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/parity/test_reference.py +794 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/parity/test_signature_contract.py +388 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/read/__init__.py +1 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/read/test_basic.py +1756 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/read/test_compression.py +664 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/read/test_coords.py +1475 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/read/test_crs.py +625 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/read/test_dtypes.py +529 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/read/test_endianness.py +120 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/read/test_georef.py +2776 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/read/test_nodata.py +3380 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/read/test_overview.py +1087 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/read/test_streaming.py +226 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/read/test_tiling.py +1853 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/release_gates/__init__.py +8 -0
- {xarray_spatial-0.9.9/xrspatial/geotiff/tests → xarray_spatial-0.10.0/xrspatial/geotiff/tests/release_gates}/test_features.py +1278 -104
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/release_gates/test_stable_features.py +2590 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/geotiff/tests/test_edge_cases.py +21 -19
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/test_fuzz_hypothesis.py +431 -0
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_polish_1488.py → xarray_spatial-0.10.0/xrspatial/geotiff/tests/test_polish.py +160 -21
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/test_round_trip.py +1112 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/geotiff/tests/test_security.py +407 -30
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/test_shutdown_cleanup_2486.py +163 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/unit/__init__.py +7 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/unit/test_codec_roundtrip.py +1360 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/unit/test_compression.py +336 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/unit/test_geotags.py +933 -0
- {xarray_spatial-0.9.9/xrspatial/geotiff/tests → xarray_spatial-0.10.0/xrspatial/geotiff/tests/unit}/test_header.py +121 -52
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/unit/test_ifd.py +1423 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/unit/test_input_validation.py +1772 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/unit/test_metadata.py +1820 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/unit/test_photometric.py +844 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/unit/test_predictor.py +1242 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/unit/test_safe_xml.py +350 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/unit/test_signatures.py +3252 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/vrt/__init__.py +1 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/vrt/test_dtype_conversion.py +1354 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/vrt/test_metadata.py +1818 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/vrt/test_missing_sources.py +888 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/vrt/test_parity.py +1147 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/vrt/test_validation.py +1894 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/vrt/test_window.py +1305 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/write/__init__.py +0 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/write/test_basic.py +2617 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/write/test_bigtiff.py +580 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/write/test_cog.py +2273 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/write/test_crs.py +1136 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/write/test_nodata.py +767 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/write/test_overview.py +2679 -0
- xarray_spatial-0.10.0/xrspatial/geotiff/tests/write/test_streaming.py +1157 -0
- xarray_spatial-0.10.0/xrspatial/hydro/tests/__init__.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/polygonize.py +384 -92
- xarray_spatial-0.10.0/xrspatial/rasterize.py +3338 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/reproject/__init__.py +685 -87
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/reproject/_crs_utils.py +62 -3
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/reproject/_grid.py +95 -7
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/reproject/_itrf.py +40 -4
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/reproject/_vertical.py +36 -9
- xarray_spatial-0.10.0/xrspatial/tests/__init__.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/bench_reproject_vs_rioxarray.py +2 -2
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_accessor.py +74 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_focal.py +22 -49
- xarray_spatial-0.10.0/xrspatial/tests/test_optional_shapely.py +81 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_polygonize.py +416 -0
- xarray_spatial-0.10.0/xrspatial/tests/test_polygonize_coverage_2026_05_19.py +713 -0
- xarray_spatial-0.10.0/xrspatial/tests/test_polygonize_issue_2172.py +254 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_rasterize.py +937 -0
- xarray_spatial-0.10.0/xrspatial/tests/test_rasterize_all_touched_supercover_2169.py +197 -0
- xarray_spatial-0.10.0/xrspatial/tests/test_rasterize_coverage_2026_05_17.py +604 -0
- xarray_spatial-0.10.0/xrspatial/tests/test_rasterize_coverage_2026_05_21.py +494 -0
- xarray_spatial-0.10.0/xrspatial/tests/test_rasterize_gpu_race_2167.py +231 -0
- xarray_spatial-0.10.0/xrspatial/tests/test_rasterize_nan_propagation_2255.py +161 -0
- xarray_spatial-0.10.0/xrspatial/tests/test_rasterize_signature_annot_2250.py +45 -0
- xarray_spatial-0.10.0/xrspatial/tests/test_rasterize_tile_props_slice_2020.py +269 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_reproject.py +2537 -23
- xarray_spatial-0.9.9/.claude/commands/rockout.md +0 -103
- xarray_spatial-0.9.9/.claude/sweep-accuracy-state.csv +0 -36
- xarray_spatial-0.9.9/.claude/sweep-api-consistency-state.csv +0 -1
- xarray_spatial-0.9.9/.claude/sweep-metadata-state.csv +0 -1
- xarray_spatial-0.9.9/.claude/sweep-performance-state.csv +0 -47
- xarray_spatial-0.9.9/.claude/sweep-test-coverage-state.csv +0 -1
- xarray_spatial-0.9.9/.github/workflows/test.yml +0 -31
- xarray_spatial-0.9.9/CONTRIBUTING.md +0 -48
- xarray_spatial-0.9.9/xrspatial/geotiff/__init__.py +0 -1804
- xarray_spatial-0.9.9/xrspatial/geotiff/_compression.py +0 -971
- xarray_spatial-0.9.9/xrspatial/geotiff/_dtypes.py +0 -136
- xarray_spatial-0.9.9/xrspatial/geotiff/_geotags.py +0 -715
- xarray_spatial-0.9.9/xrspatial/geotiff/_header.py +0 -456
- xarray_spatial-0.9.9/xrspatial/geotiff/_reader.py +0 -941
- xarray_spatial-0.9.9/xrspatial/geotiff/_vrt.py +0 -521
- xarray_spatial-0.9.9/xrspatial/geotiff/_writer.py +0 -1530
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_accessor_io.py +0 -166
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_accuracy_1081.py +0 -292
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_cog.py +0 -379
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_cog_http_concurrent.py +0 -180
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_compression.py +0 -129
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_compression_level.py +0 -171
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_dtype_read.py +0 -117
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_georef_edges.py +0 -157
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_geotags.py +0 -255
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_jpeg.py +0 -151
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_jpeg2000.py +0 -186
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_lerc.py +0 -160
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_lz4.py +0 -137
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_metadata_round_trip_1484.py +0 -418
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_predictor_fp_write_1313.py +0 -203
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_predictor_multisample.py +0 -448
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_reader.py +0 -185
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_streaming_write.py +0 -334
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_vrt_write.py +0 -111
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_writer.py +0 -104
- xarray_spatial-0.9.9/xrspatial/geotiff/tests/test_writer_matrix.py +0 -253
- xarray_spatial-0.9.9/xrspatial/rasterize.py +0 -2232
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.claude/commands/backend-parity.md +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.claude/commands/bench.md +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.claude/commands/dask-notebook.md +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.claude/commands/efficiency-audit.md +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.claude/commands/new-issues.md +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.claude/commands/release-major.md +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.claude/commands/release-minor.md +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.claude/commands/user-guide-notebook.md +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.claude/commands/validate.md +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.efficiency-audit-baseline.json +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.efficiency-audit-baseline.prev.json +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.gitattributes +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.github/ISSUE_TEMPLATE/feature-proposal.md +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.github/labeler.yml +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.github/pull_request_template.md +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.github/workflows/benchmarks.yml +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.github/workflows/labeler.yml +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.github/workflows/pypi-publish.yml +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/.readthedocs.yml +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/CODE_OF_CONDUCT.md +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/Citation-styles.md +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/LICENSE.txt +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/MANIFEST.in +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/RELEASE.md +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/codecov.yml +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/pyproject.toml +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/setup.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xarray_spatial.egg-info/dependency_links.txt +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xarray_spatial.egg-info/entry_points.txt +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xarray_spatial.egg-info/not-zip-safe +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xarray_spatial.egg-info/top_level.txt +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/__init__.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/__main__.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/analytics.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/aspect.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/bilateral.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/bump.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/classify.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/contour.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/convolution.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/corridor.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/cost_distance.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/curvature.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/dasymetric.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/dataset_support.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/datasets/__init__.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/datasets/sentinel-2/blue_band.nc +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/datasets/sentinel-2/green_band.nc +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/datasets/sentinel-2/nir_band.nc +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/datasets/sentinel-2/red_band.nc +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/datasets/sentinel-2/swir1_band.nc +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/datasets/sentinel-2/swir2_band.nc +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/diagnostics.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/diffusion.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/edge_detection.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/emerging_hotspots.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/erosion.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/experimental/__init__.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/experimental/min_observable_height.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/fire.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/flood.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/focal.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/geodesic.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/geotiff/tests/__init__.py +0 -0
- {xarray_spatial-0.9.9/xrspatial/hydro/tests → xarray_spatial-0.10.0/xrspatial/geotiff/tests/attrs}/__init__.py +0 -0
- {xarray_spatial-0.9.9/xrspatial/tests → xarray_spatial-0.10.0/xrspatial/geotiff/tests/integration}/__init__.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/glcm.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/gpu_rtx/__init__.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/gpu_rtx/_memory.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/gpu_rtx/cuda_utils.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/gpu_rtx/hillshade.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/gpu_rtx/mesh_utils.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/gpu_rtx/viewshed.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hillshade.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/__init__.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/_boundary_store.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/basin_d8.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/fill_d8.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/flow_accumulation_d8.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/flow_accumulation_dinf.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/flow_accumulation_mfd.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/flow_direction_d8.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/flow_direction_dinf.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/flow_direction_mfd.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/flow_length_d8.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/flow_length_dinf.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/flow_length_mfd.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/flow_path_d8.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/flow_path_dinf.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/flow_path_mfd.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/hand_d8.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/hand_dinf.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/hand_mfd.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/sink_d8.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/snap_pour_point_d8.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/stream_link_d8.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/stream_link_dinf.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/stream_link_mfd.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/stream_order_d8.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/stream_order_dinf.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/stream_order_mfd.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/conftest.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_basin_d8.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_fill_d8.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_flow_accumulation_d8.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_flow_accumulation_dinf.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_flow_accumulation_mfd.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_flow_direction_d8.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_flow_direction_dinf.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_flow_direction_mfd.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_flow_length_d8.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_flow_length_dinf.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_flow_length_mfd.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_flow_path_d8.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_flow_path_dinf.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_flow_path_mfd.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_hand_d8.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_hand_dinf.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_hand_mfd.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_sink_d8.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_snap_pour_point_d8.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_stream_link_d8.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_stream_link_dinf.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_stream_link_mfd.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_stream_order_d8.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_stream_order_dinf.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_stream_order_mfd.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_twi_d8.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_validate_cellsize.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_validate_scalar_params.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_validate_secondary_args.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_watershed_d8.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_watershed_dinf.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/tests/test_watershed_mfd.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/twi_d8.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/watershed_d8.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/watershed_dinf.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/hydro/watershed_mfd.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/interpolate/__init__.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/interpolate/_idw.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/interpolate/_kriging.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/interpolate/_spline.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/interpolate/_validation.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/kde.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/mahalanobis.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/mcda/__init__.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/mcda/combine.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/mcda/constrain.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/mcda/sensitivity.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/mcda/standardize.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/mcda/weights.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/morphology.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/multispectral.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/normalize.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/pathfinding.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/perlin.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/polygon_clip.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/preview.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/proximity.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/reproject/_datum_grids.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/reproject/_interpolate.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/reproject/_lite_crs.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/reproject/_merge.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/reproject/_projections.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/reproject/_projections_cuda.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/reproject/_transform.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/reproject/grids/at_bev_AT_GIS_GRID.tif +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/reproject/grids/au_icsm_A66_National_13_09_01.tif +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/reproject/grids/be_ign_bd72lb72_etrs89lb08.tif +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/reproject/grids/ch_swisstopo_CHENyx06_ETRS.tif +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/reproject/grids/de_adv_BETA2007.tif +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/reproject/grids/es_ign_SPED2ETV2.tif +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/reproject/grids/nl_nsgi_rdcorr2018.tif +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/reproject/grids/pt_dgt_D73_ETRS89_geo.tif +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/reproject/grids/uk_os_OSTN15_NTv2_OSGBtoETRS.tif +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/reproject/grids/us_nga_egm96_15.tif +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/reproject/grids/us_noaa_alaska.tif +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/reproject/grids/us_noaa_conus.tif +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/reproject/grids/us_noaa_hawaii.tif +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/reproject/grids/us_noaa_nadcon5_nad27_nad83_1986_conus.tif +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/reproject/grids/us_noaa_prvi.tif +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/resample.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/sieve.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/sky_view_factor.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/slope.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/surface_distance.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/terrain.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/terrain_metrics.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/conftest.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/general_checks.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_analytics.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_aspect.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_balanced_allocation.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_bilateral.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_bump.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_classify.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_contour.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_convolution.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_corridor.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_cost_distance.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_curvature.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_dask_cupy_gaps.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_dask_laziness.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_dasymetric.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_dataset_support.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_datasets.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_diagnostics.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_diffusion.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_edge_detection.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_emerging_hotspots.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_erosion.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_fire.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_flood.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_fused_overlap.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_geodesic_aspect.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_geodesic_slope.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_glcm.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_glcm_metric_order.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_gpu_rtx_memory.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_gpu_rtx_mesh.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_hillshade.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_hypsometric_integral.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_interpolation.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_kde.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_lite_crs.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_mahalanobis.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_mcda.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_min_observable_height.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_morphology.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_morphology_derived.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_multi_overlap.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_multispectral.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_normalize.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_northness_eastness.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_pathfinding.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_perlin.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_polygon_clip.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_preview.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_proximity.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_rasterize_accuracy.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_rechunk_no_shuffle.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_resample.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_sieve.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_sieve_gdal_parity.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_sky_view_factor.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_slope.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_surface_distance.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_terrain.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_terrain_metrics.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_utils.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_validation.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_viewshed.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_visibility.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/tests/test_zonal.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/utils.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/viewshed.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/visibility.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/worley.py +0 -0
- {xarray_spatial-0.9.9 → xarray_spatial-0.10.0}/xrspatial/zonal.py +0 -0
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
# Deep Sweep: Run every sweep-* command focused on a single module
|
|
2
|
+
|
|
3
|
+
Pick one xrspatial module and dispatch every `/sweep-*` command at it in
|
|
4
|
+
parallel. Each sub-sweep follows the audit template embedded in its own
|
|
5
|
+
`.claude/commands/sweep-*.md` file, runs `/rockout` for HIGH/MEDIUM findings
|
|
6
|
+
when the sweep specifies it, and updates its own
|
|
7
|
+
`.claude/sweep-{type}-state.csv` row for the target module.
|
|
8
|
+
|
|
9
|
+
New sweeps are picked up automatically. Drop a
|
|
10
|
+
`.claude/commands/sweep-XYZ.md` into the commands directory and the next
|
|
11
|
+
`/deep-sweep` run will dispatch it alongside the others.
|
|
12
|
+
|
|
13
|
+
Required first argument: the module name (e.g. `geotiff`, `slope`, `hydro`).
|
|
14
|
+
Optional flags: $ARGUMENTS
|
|
15
|
+
(e.g. `geotiff --only-sweep security,performance`,
|
|
16
|
+
`viewshed --exclude-sweep test-coverage`,
|
|
17
|
+
`slope --no-fix`,
|
|
18
|
+
`reproject --reset-state`)
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Step 0 -- Parse arguments and snapshot main-checkout state
|
|
23
|
+
|
|
24
|
+
The first positional token in `$ARGUMENTS` is the module name. It is
|
|
25
|
+
required. If `$ARGUMENTS` is empty or starts with a flag, stop and ask the
|
|
26
|
+
user which module to deep-sweep.
|
|
27
|
+
|
|
28
|
+
Capture the main checkout's branch as `DEEP_SWEEP_START_BRANCH` so Step
|
|
29
|
+
5.5 can verify the sweeps left it untouched:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
DEEP_SWEEP_START_BRANCH="$(git -C $(git rev-parse --show-toplevel) branch --show-current)"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
If the main checkout has uncommitted changes when /deep-sweep starts,
|
|
36
|
+
note them. Step 5.5 will diff against this snapshot, not the empty
|
|
37
|
+
state, so existing dirtiness is not mistaken for a sweep breach.
|
|
38
|
+
|
|
39
|
+
Then parse flags (multiple may combine):
|
|
40
|
+
|
|
41
|
+
| Flag | Effect |
|
|
42
|
+
|------|--------|
|
|
43
|
+
| `--only-sweep s1,s2` | Only dispatch the named sweeps. Names are the suffix after `sweep-` (e.g. `security`, `performance`, `api-consistency`). |
|
|
44
|
+
| `--exclude-sweep s1,s2` | Skip the named sweeps. |
|
|
45
|
+
| `--no-fix` | Pass `--no-fix` semantics to every dispatched sweep: subagent audits only, no `/rockout`, no PR. State CSV is still updated. |
|
|
46
|
+
| `--reset-state` | Before dispatching, delete the target module's row from every `.claude/sweep-*-state.csv` so the audit is treated as never-inspected. Do NOT delete other modules' rows. |
|
|
47
|
+
|
|
48
|
+
## Step 1 -- Validate the module
|
|
49
|
+
|
|
50
|
+
Determine the module's files under `xrspatial/`:
|
|
51
|
+
|
|
52
|
+
- If `xrspatial/{module}.py` exists, the module is a single file at that path.
|
|
53
|
+
- Else if `xrspatial/{module}/` is a directory, the module is a subpackage.
|
|
54
|
+
List all `.py` files under it (excluding `__init__.py`).
|
|
55
|
+
- Otherwise, stop and report that `{module}` was not found, listing the
|
|
56
|
+
available top-level `.py` files and subpackage directories under
|
|
57
|
+
`xrspatial/` so the user can correct the name.
|
|
58
|
+
|
|
59
|
+
Skip names that the individual sweeps already exclude from their discovery:
|
|
60
|
+
`__init__`, `_version`, `__main__`, `utils`, `accessor`, `preview`,
|
|
61
|
+
`dataset_support`, `diagnostics`, `analytics`. If the user passes one of
|
|
62
|
+
these, stop and explain that these modules are not in scope for the
|
|
63
|
+
per-module sweeps.
|
|
64
|
+
|
|
65
|
+
## Step 2 -- Discover sweep commands
|
|
66
|
+
|
|
67
|
+
List all files matching `.claude/commands/sweep-*.md`. For each, the sweep
|
|
68
|
+
name is the basename without `sweep-` prefix and `.md` suffix
|
|
69
|
+
(e.g. `.claude/commands/sweep-security.md` → `security`). Build the list
|
|
70
|
+
in sorted order so the dispatch table is deterministic.
|
|
71
|
+
|
|
72
|
+
Apply `--only-sweep` / `--exclude-sweep` filters. If the resulting list is
|
|
73
|
+
empty, stop and report which filters eliminated everything.
|
|
74
|
+
|
|
75
|
+
For each remaining sweep, record:
|
|
76
|
+
- `sweep_name` (e.g. `security`)
|
|
77
|
+
- `sweep_file` (path to the `.md`)
|
|
78
|
+
- `state_file` (`.claude/sweep-{sweep_name}-state.csv`)
|
|
79
|
+
|
|
80
|
+
## Step 3 -- Gather shared module metadata
|
|
81
|
+
|
|
82
|
+
Collect once and pass to every subagent (each sweep file lists the metadata
|
|
83
|
+
it needs; the union below covers all current sweeps):
|
|
84
|
+
|
|
85
|
+
| Field | How |
|
|
86
|
+
|-------|-----|
|
|
87
|
+
| **module_files** | from Step 1 |
|
|
88
|
+
| **last_modified** | `git log -1 --format=%aI -- <path>` (for subpackages, most recent file) |
|
|
89
|
+
| **total_commits** | `git log --oneline -- <path> \| wc -l` |
|
|
90
|
+
| **loc** | `wc -l < <path>` (for subpackages, sum all files) |
|
|
91
|
+
| **has_cuda_kernels** | grep file(s) for `@cuda.jit` |
|
|
92
|
+
| **has_file_io** | grep file(s) for `open(`, `mkstemp`, `os.path`, `pathlib` |
|
|
93
|
+
| **has_numba_jit** | grep file(s) for `@ngjit`, `@njit`, `@jit`, `numba.jit` |
|
|
94
|
+
| **allocates_from_dims** | grep file(s) for `np.empty(height`, `np.zeros(height`, `np.empty(H`, `cp.empty(`, and width variants |
|
|
95
|
+
| **has_shared_memory** | grep file(s) for `cuda.shared.array` |
|
|
96
|
+
| **has_dask_backend** | grep file(s) for `_run_dask`, `map_overlap`, `map_blocks` |
|
|
97
|
+
| **has_cuda_backend** | grep file(s) for `@cuda.jit`, `import cupy` |
|
|
98
|
+
|
|
99
|
+
Also detect CUDA availability once:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
python -c "from numba import cuda; print(cuda.is_available())" 2>/dev/null
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Capture as `CUDA_AVAILABLE` (`true` / `false`).
|
|
106
|
+
|
|
107
|
+
## Step 4 -- Handle `--reset-state`
|
|
108
|
+
|
|
109
|
+
If `--reset-state` was passed, for each state file in scope:
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
import csv
|
|
113
|
+
from pathlib import Path
|
|
114
|
+
|
|
115
|
+
path = Path("{state_file}")
|
|
116
|
+
if not path.exists():
|
|
117
|
+
continue
|
|
118
|
+
with path.open() as f:
|
|
119
|
+
reader = csv.DictReader(f)
|
|
120
|
+
header = reader.fieldnames
|
|
121
|
+
rows = [r for r in reader if r["module"] != "{module}"]
|
|
122
|
+
with path.open("w", newline="") as f:
|
|
123
|
+
w = csv.DictWriter(f, fieldnames=header, quoting=csv.QUOTE_MINIMAL)
|
|
124
|
+
w.writeheader()
|
|
125
|
+
for r in rows:
|
|
126
|
+
w.writerow(r)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
This removes only the target module's row from each state file, leaving
|
|
130
|
+
other modules' history intact. Do this before dispatching the subagents so
|
|
131
|
+
they each see a clean slate for this module.
|
|
132
|
+
|
|
133
|
+
## Step 5 -- Dispatch one subagent per sweep, in parallel
|
|
134
|
+
|
|
135
|
+
Print a short dispatch table:
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
Deep-sweeping module "{module}" across {N} sweeps:
|
|
139
|
+
- security → .claude/sweep-security-state.csv
|
|
140
|
+
- performance → .claude/sweep-performance-state.csv
|
|
141
|
+
- accuracy → .claude/sweep-accuracy-state.csv
|
|
142
|
+
...
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Then in a **single message**, launch one Agent per sweep with
|
|
146
|
+
`isolation: "worktree"` and `mode: "auto"` so they run concurrently in
|
|
147
|
+
separate worktrees. Use the prompt template below for every agent,
|
|
148
|
+
substituting `{sweep_name}`, `{sweep_file}`, `{state_file}`, `{module}`,
|
|
149
|
+
`{module_files}`, `{loc}`, `{commits}`, `{cuda_available}`, `{today}`, and
|
|
150
|
+
the boolean metadata flags. The `{today}` value is critical: it's woven
|
|
151
|
+
into the deterministic branch name `deep-sweep-{sweep_name}-{module}-{today}`
|
|
152
|
+
that each sibling rebases its worktree onto, and the parent later checks
|
|
153
|
+
those names for uniqueness.
|
|
154
|
+
|
|
155
|
+
### Subagent prompt template
|
|
156
|
+
|
|
157
|
+
```
|
|
158
|
+
You are running ONE specific sweep -- "{sweep_name}" -- against a single
|
|
159
|
+
xrspatial module: "{module}".
|
|
160
|
+
|
|
161
|
+
The parent command (/deep-sweep) has already chosen this module and is
|
|
162
|
+
dispatching every sweep against it in parallel. Your job is to behave
|
|
163
|
+
exactly as the embedded subagent prompt in
|
|
164
|
+
.claude/commands/sweep-{sweep_name}.md would, but skip module discovery
|
|
165
|
+
and scoring -- the module is already chosen.
|
|
166
|
+
|
|
167
|
+
## WORKTREE ISOLATION CONTRACT (read first, enforce throughout)
|
|
168
|
+
|
|
169
|
+
You were dispatched with `isolation: "worktree"`. That means a dedicated
|
|
170
|
+
git worktree was created for you, and your CWD at launch IS that
|
|
171
|
+
worktree directory. Several parallel siblings are running the other
|
|
172
|
+
sweeps against the same module right now. If you operate outside your
|
|
173
|
+
worktree, you will collide with them and your commits will land on the
|
|
174
|
+
wrong branch.
|
|
175
|
+
|
|
176
|
+
**Step ISO-1 (run BEFORE anything else, before reading any sweep file):**
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
DEEP_SWEEP_WT="$(pwd)"
|
|
180
|
+
DEEP_SWEEP_TOP="$(git rev-parse --show-toplevel)"
|
|
181
|
+
DEEP_SWEEP_BRANCH="$(git branch --show-current)"
|
|
182
|
+
echo "wt=$DEEP_SWEEP_WT top=$DEEP_SWEEP_TOP branch=$DEEP_SWEEP_BRANCH"
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Assert ALL of the following. If any fails, STOP immediately, do NOT
|
|
186
|
+
make any commits, and report exactly `WORKTREE_ISOLATION_FAILED:
|
|
187
|
+
<reason>` back to the parent:
|
|
188
|
+
|
|
189
|
+
- `$DEEP_SWEEP_WT` equals `$DEEP_SWEEP_TOP` (you are at the worktree
|
|
190
|
+
root, not in a subdirectory of some other checkout).
|
|
191
|
+
- `$DEEP_SWEEP_TOP` contains the segment `.claude/worktrees/agent-`
|
|
192
|
+
(you are inside an isolated worktree, not the user's main checkout).
|
|
193
|
+
- `$DEEP_SWEEP_BRANCH` is NOT `main` and NOT `master`.
|
|
194
|
+
- `$DEEP_SWEEP_BRANCH` does NOT already match a branch created by
|
|
195
|
+
another deep-sweep sibling. Specifically, reject branches matching
|
|
196
|
+
`deep-sweep-*-{module}-*` whose `{sweep_name}` segment is NOT
|
|
197
|
+
"{sweep_name}". (If you find yourself on a sibling's branch, the
|
|
198
|
+
Agent harness has handed you the wrong worktree -- bail out.)
|
|
199
|
+
|
|
200
|
+
**Step ISO-2 (immediately after ISO-1, before any audit work):**
|
|
201
|
+
|
|
202
|
+
Rename your branch to a deterministic, sweep-specific name so /rockout
|
|
203
|
+
calls and state-CSV commits cannot collide with siblings:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
DEEP_SWEEP_TARGET_BRANCH="deep-sweep-{sweep_name}-{module}-{today}"
|
|
207
|
+
if [ "$DEEP_SWEEP_BRANCH" != "$DEEP_SWEEP_TARGET_BRANCH" ]; then
|
|
208
|
+
git branch -m "$DEEP_SWEEP_TARGET_BRANCH"
|
|
209
|
+
DEEP_SWEEP_BRANCH="$DEEP_SWEEP_TARGET_BRANCH"
|
|
210
|
+
fi
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
From this point on, every git operation (add, commit, push,
|
|
214
|
+
checkout, rebase) MUST be executed from `$DEEP_SWEEP_WT`. Do NOT use
|
|
215
|
+
absolute paths into the user's main checkout. Do NOT `cd` away from
|
|
216
|
+
`$DEEP_SWEEP_WT`. If a tool resolves an absolute path back to the
|
|
217
|
+
main checkout (e.g. `/home/.../xarray-spatial-contrib/...`), pass the
|
|
218
|
+
worktree-relative path instead.
|
|
219
|
+
|
|
220
|
+
**Step ISO-3 (before EVERY commit you make, parent or /rockout-driven):**
|
|
221
|
+
|
|
222
|
+
Re-check that you are still on the right branch in the right
|
|
223
|
+
directory. /rockout in particular may switch branches; if so, it
|
|
224
|
+
must do so from within `$DEEP_SWEEP_WT` and the new branch name
|
|
225
|
+
must start with `deep-sweep-{sweep_name}-{module}-` (use
|
|
226
|
+
`--branch-prefix` or equivalent if /rockout exposes one; otherwise
|
|
227
|
+
create your /rockout branches manually from
|
|
228
|
+
`$DEEP_SWEEP_TARGET_BRANCH` rather than letting /rockout pick a
|
|
229
|
+
plain `issue-NNNN` name that could collide):
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
[ "$(pwd)" = "$DEEP_SWEEP_WT" ] || { echo "CWD drift"; exit 1; }
|
|
233
|
+
case "$(git branch --show-current)" in
|
|
234
|
+
deep-sweep-{sweep_name}-{module}-*) : ;;
|
|
235
|
+
*) echo "branch drift: $(git branch --show-current)"; exit 1 ;;
|
|
236
|
+
esac
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
A failed re-check is an isolation breach. Stop, do not commit, and
|
|
240
|
+
report back.
|
|
241
|
+
|
|
242
|
+
**Step ISO-4 (when filing PRs):**
|
|
243
|
+
|
|
244
|
+
If /rockout produces one or more PRs, every PR must be pushed from a
|
|
245
|
+
branch matching `deep-sweep-{sweep_name}-{module}-*`. Do NOT push to
|
|
246
|
+
`main`. Do NOT push to a sibling's branch name. If the sweep template
|
|
247
|
+
mandates one PR per finding (e.g. security: one fix per PR), use
|
|
248
|
+
suffixes like `deep-sweep-{sweep_name}-{module}-{today}-01`,
|
|
249
|
+
`-02`, etc., all branched off `$DEEP_SWEEP_TARGET_BRANCH`.
|
|
250
|
+
|
|
251
|
+
## Bootstrapping steps (after ISO-1 / ISO-2 pass)
|
|
252
|
+
|
|
253
|
+
1. Read the sweep definition: {sweep_file}
|
|
254
|
+
|
|
255
|
+
Inside it, locate the "subagent prompt template" (a fenced block under
|
|
256
|
+
a heading like "Step 5b" or "Step 3b" titled "Launch subagents"). That
|
|
257
|
+
block is what an individual sweep dispatches to its own audit workers.
|
|
258
|
+
You are going to act as that worker for module "{module}".
|
|
259
|
+
|
|
260
|
+
2. Pre-collected metadata for "{module}":
|
|
261
|
+
|
|
262
|
+
- module_files : {module_files}
|
|
263
|
+
- loc : {loc}
|
|
264
|
+
- total_commits : {commits}
|
|
265
|
+
- last_modified : {last_modified}
|
|
266
|
+
- has_cuda_kernels : {has_cuda_kernels}
|
|
267
|
+
- has_file_io : {has_file_io}
|
|
268
|
+
- has_numba_jit : {has_numba_jit}
|
|
269
|
+
- allocates_from_dims: {allocates_from_dims}
|
|
270
|
+
- has_shared_memory : {has_shared_memory}
|
|
271
|
+
- has_dask_backend : {has_dask_backend}
|
|
272
|
+
- has_cuda_backend : {has_cuda_backend}
|
|
273
|
+
- CUDA_AVAILABLE : {cuda_available}
|
|
274
|
+
|
|
275
|
+
Use only the fields the sweep's template actually references. Ignore
|
|
276
|
+
ones it does not mention.
|
|
277
|
+
|
|
278
|
+
3. Follow the sweep's embedded subagent prompt verbatim against this
|
|
279
|
+
module. That means:
|
|
280
|
+
|
|
281
|
+
- Read every file the template tells you to read (module files, utils,
|
|
282
|
+
tests, general_checks.py, etc.).
|
|
283
|
+
- Run every audit category the template lists. Only flag issues
|
|
284
|
+
ACTUALLY present in the code -- false positives are worse than
|
|
285
|
+
missed issues.
|
|
286
|
+
- If the template instructs the worker to run /rockout for
|
|
287
|
+
HIGH/MEDIUM findings, do so {fix_mode_note}, observing the
|
|
288
|
+
worktree-isolation contract above (ISO-3 / ISO-4).
|
|
289
|
+
- Update the sweep's state CSV ({state_file}) using the read-update-
|
|
290
|
+
write Python pattern the template specifies. Key by module name;
|
|
291
|
+
last write wins on duplicates. Use today's ISO date
|
|
292
|
+
({today}) for last_inspected. Use empty strings (not "null") for
|
|
293
|
+
missing fields.
|
|
294
|
+
- `git add {state_file}` and commit it on YOUR worktree branch
|
|
295
|
+
(`$DEEP_SWEEP_TARGET_BRANCH`) so the state update lands in any
|
|
296
|
+
resulting PR. Run ISO-3's re-check immediately before the commit.
|
|
297
|
+
If you did not file a PR, still commit the state update on the
|
|
298
|
+
worktree branch -- the parent will surface the branch path in its
|
|
299
|
+
summary.
|
|
300
|
+
|
|
301
|
+
4. The sweep file may have its own CUDA-availability conditional (run
|
|
302
|
+
GPU paths vs. static review only). Honour it using CUDA_AVAILABLE
|
|
303
|
+
above. If CUDA is unavailable and the sweep specifies adding a
|
|
304
|
+
"cuda-unavailable" token to notes, do so.
|
|
305
|
+
|
|
306
|
+
**Hard rules (override any conflicting hint in the template):**
|
|
307
|
+
|
|
308
|
+
- Operate ONLY on module "{module}". Do not score, rank, or audit any
|
|
309
|
+
other module. Do not re-discover the module list.
|
|
310
|
+
- Do not modify other modules' rows in {state_file}. Only your own
|
|
311
|
+
module's row is touched.
|
|
312
|
+
- Do not call `.compute()` in any dask graph-construction probe.
|
|
313
|
+
- If the sweep template would normally launch its own sub-subagents,
|
|
314
|
+
do NOT recurse -- you ARE the worker. Inline the work it would
|
|
315
|
+
delegate.
|
|
316
|
+
- All commits and pushes happen from `$DEEP_SWEEP_WT` on a branch
|
|
317
|
+
starting with `deep-sweep-{sweep_name}-{module}-`. Never on `main`,
|
|
318
|
+
never in the user's main checkout, never on a sibling sweep's branch.
|
|
319
|
+
- {fix_mode_rule}
|
|
320
|
+
|
|
321
|
+
**Final report (mandatory):**
|
|
322
|
+
|
|
323
|
+
When you finish, report a short summary including, in addition to the
|
|
324
|
+
audit content, an isolation footer with the literal values of
|
|
325
|
+
`$DEEP_SWEEP_WT`, `$DEEP_SWEEP_TARGET_BRANCH`, and the SHA of the
|
|
326
|
+
state-CSV commit. The parent uses these to verify the contract held:
|
|
327
|
+
|
|
328
|
+
```
|
|
329
|
+
Findings: <N CRITICAL>, <N HIGH>, <N MEDIUM>, <N LOW>
|
|
330
|
+
/rockout: <not-run | PRs: #NNNN, #NNNN>
|
|
331
|
+
Isolation:
|
|
332
|
+
worktree: <$DEEP_SWEEP_WT>
|
|
333
|
+
branch: <$DEEP_SWEEP_TARGET_BRANCH>
|
|
334
|
+
state-commit: <SHA>
|
|
335
|
+
```
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
Where `{fix_mode_note}` and `{fix_mode_rule}` are:
|
|
339
|
+
|
|
340
|
+
- If `--no-fix` was NOT passed:
|
|
341
|
+
- `{fix_mode_note}` = `end-to-end (GitHub issue, worktree branch, fix, tests, PR)`
|
|
342
|
+
- `{fix_mode_rule}` = `Run /rockout for HIGH/MEDIUM/CRITICAL findings as the sweep template specifies. LOW findings: document, do not fix.`
|
|
343
|
+
- If `--no-fix` WAS passed:
|
|
344
|
+
- `{fix_mode_note}` = `-- skipped, --no-fix is set`
|
|
345
|
+
- `{fix_mode_rule}` = `Do NOT run /rockout. Document findings in the state CSV's notes field and your summary. This run is audit-only.`
|
|
346
|
+
|
|
347
|
+
And `{today}` is the current date in ISO 8601 (use the `currentDate`
|
|
348
|
+
context value if available; otherwise `date +%Y-%m-%d`).
|
|
349
|
+
|
|
350
|
+
## Step 5.5 -- Verify the worktree-isolation contract held
|
|
351
|
+
|
|
352
|
+
Before printing the user-facing results table, parse each agent's
|
|
353
|
+
returned summary for its "Isolation" footer (worktree path, branch
|
|
354
|
+
name, state-commit SHA). Then verify:
|
|
355
|
+
|
|
356
|
+
1. **No `WORKTREE_ISOLATION_FAILED` markers.** If any agent returned
|
|
357
|
+
that token, mark its row `ISOLATION FAILED` in the results table
|
|
358
|
+
and surface the agent's full final message verbatim. Do not treat
|
|
359
|
+
its findings as merged-ready.
|
|
360
|
+
2. **Branch uniqueness.** Every agent must be on a distinct branch.
|
|
361
|
+
Expected pattern: `deep-sweep-{sweep_name}-{module}-{today}`
|
|
362
|
+
(with optional `-NN` suffix for /rockout fan-out). Reject any
|
|
363
|
+
duplicates and any branch equal to `main` / `master`.
|
|
364
|
+
3. **Worktree distinctness.** Every agent's reported worktree path
|
|
365
|
+
must be unique and must contain `.claude/worktrees/agent-`.
|
|
366
|
+
4. **Main checkout untouched.** Run:
|
|
367
|
+
|
|
368
|
+
```bash
|
|
369
|
+
git -C $(git rev-parse --show-toplevel) rev-parse --abbrev-ref HEAD
|
|
370
|
+
git -C $(git rev-parse --show-toplevel) status --porcelain
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
The main checkout's HEAD branch must be unchanged from what it was
|
|
374
|
+
before /deep-sweep started (capture it in Step 0 as
|
|
375
|
+
`DEEP_SWEEP_START_BRANCH`). The porcelain output should contain no
|
|
376
|
+
commits or modifications introduced by sweep agents (a still-untracked
|
|
377
|
+
`.claude/commands/*.md` from the current session is fine; new commits
|
|
378
|
+
on the current branch from a sweep agent are NOT).
|
|
379
|
+
|
|
380
|
+
If any of (1)-(4) fails, print a clearly-labeled
|
|
381
|
+
`### Isolation contract breached` section ABOVE the results table,
|
|
382
|
+
listing every breach and which agent caused it, so the user can decide
|
|
383
|
+
whether to keep the produced PRs or unwind them. Do not silently
|
|
384
|
+
proceed.
|
|
385
|
+
|
|
386
|
+
## Step 6 -- Wait, collect, and print the summary
|
|
387
|
+
|
|
388
|
+
All Agent calls run in the foreground in parallel. Once they return, print
|
|
389
|
+
a single results table:
|
|
390
|
+
|
|
391
|
+
```
|
|
392
|
+
| Sweep | Findings | /rockout PR | State row written |
|
|
393
|
+
|-----------------|-----------------|-------------|-------------------|
|
|
394
|
+
| security | 0 HIGH, 1 MED | #1567 | yes |
|
|
395
|
+
| performance | 2 HIGH | #1568 | yes |
|
|
396
|
+
| accuracy | clean | -- | yes |
|
|
397
|
+
| api-consistency | 1 HIGH | #1569 | yes |
|
|
398
|
+
| metadata | 0 | -- | yes |
|
|
399
|
+
| test-coverage | 3 MED | #1570 | yes |
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
Pull the values from each agent's returned summary. If an agent failed,
|
|
403
|
+
mark that row with `ERROR` in the findings column and surface the agent's
|
|
404
|
+
final message verbatim below the table so the user can decide whether to
|
|
405
|
+
re-run that single sweep manually (`/sweep-{sweep_name}`).
|
|
406
|
+
|
|
407
|
+
Finally, list the worktree branches each agent left behind so the user can
|
|
408
|
+
inspect or push them.
|
|
409
|
+
|
|
410
|
+
---
|
|
411
|
+
|
|
412
|
+
## General rules
|
|
413
|
+
|
|
414
|
+
- Never modify source files from the parent. All edits happen inside
|
|
415
|
+
per-sweep worktrees via the subagents.
|
|
416
|
+
- The deliverable from the parent is: validated module, dispatch table,
|
|
417
|
+
parallel agents, results table. Keep parent output concise.
|
|
418
|
+
- Each sweep's state CSV is registered with `merge=union` in
|
|
419
|
+
`.gitattributes`, so the N concurrent state updates auto-merge cleanly
|
|
420
|
+
even though they all touch the same module's row in different worktrees
|
|
421
|
+
-- the last write per row wins, which is the read-update-write semantics
|
|
422
|
+
the sweep templates already use.
|
|
423
|
+
- If a sweep template later changes its state-file schema or its audit
|
|
424
|
+
categories, deep-sweep picks up the change automatically the next time
|
|
425
|
+
it runs, because each subagent re-reads its sweep file on dispatch.
|
|
426
|
+
- If $ARGUMENTS provides a module that has no entry in any state file
|
|
427
|
+
(never inspected before), that is fine -- the subagents will create the
|
|
428
|
+
first row.
|
|
429
|
+
- /deep-sweep is not for triaging the whole codebase. For that, run the
|
|
430
|
+
individual `/sweep-*` commands; they score and pick the highest-priority
|
|
431
|
+
modules. Use /deep-sweep when you already know which module needs a
|
|
432
|
+
full-spectrum audit.
|
|
@@ -13,13 +13,36 @@ $ARGUMENTS
|
|
|
13
13
|
3. Increment the **patch** component: `X.Y.Z` -> `X.Y.(Z+1)`.
|
|
14
14
|
4. Store the new version string (without `v` prefix) for later steps.
|
|
15
15
|
|
|
16
|
-
## Step 2 -- Create a release branch
|
|
16
|
+
## Step 2 -- Create a release branch in a worktree
|
|
17
|
+
|
|
18
|
+
The main checkout MUST stay on `main` -- the release branch lives in a
|
|
19
|
+
dedicated worktree. All remaining steps (changelog edits, commit,
|
|
20
|
+
push, PR) run from that worktree.
|
|
17
21
|
|
|
18
22
|
```bash
|
|
19
|
-
git
|
|
20
|
-
git
|
|
23
|
+
RELEASE_MAIN="$(git rev-parse --show-toplevel)"
|
|
24
|
+
git -C "$RELEASE_MAIN" fetch origin main
|
|
25
|
+
RELEASE_MAIN_BRANCH="$(git -C "$RELEASE_MAIN" branch --show-current)"
|
|
26
|
+
if [ "$RELEASE_MAIN_BRANCH" = "main" ]; then
|
|
27
|
+
git -C "$RELEASE_MAIN" pull --ff-only origin main
|
|
28
|
+
fi
|
|
29
|
+
git -C "$RELEASE_MAIN" worktree add \
|
|
30
|
+
".claude/worktrees/release-vX.Y.Z" -b "release/vX.Y.Z" origin/main
|
|
31
|
+
RELEASE_WT="$RELEASE_MAIN/.claude/worktrees/release-vX.Y.Z"
|
|
32
|
+
cd "$RELEASE_WT"
|
|
21
33
|
```
|
|
22
34
|
|
|
35
|
+
Verify isolation -- assert ALL of the following before continuing:
|
|
36
|
+
- `$(pwd)` equals `$RELEASE_WT`.
|
|
37
|
+
- `git branch --show-current` is `release/vX.Y.Z`.
|
|
38
|
+
- `git -C "$RELEASE_MAIN" branch --show-current` is still `main`
|
|
39
|
+
(the main checkout's branch did NOT change).
|
|
40
|
+
|
|
41
|
+
For every remaining step, use paths anchored at `$RELEASE_WT` for
|
|
42
|
+
Edit / Read / Write tool calls -- do NOT edit files under
|
|
43
|
+
`$RELEASE_MAIN`. Re-check `pwd` and the current branch before
|
|
44
|
+
every `git commit`.
|
|
45
|
+
|
|
23
46
|
## Step 3 -- Update CHANGELOG.md
|
|
24
47
|
|
|
25
48
|
1. Run `git log --pretty=format:"- %s" <latest_tag>..HEAD` to collect
|
|
@@ -61,14 +84,25 @@ gh pr merge <PR_NUMBER> --merge --delete-branch
|
|
|
61
84
|
|
|
62
85
|
## Step 7 -- Tag the release
|
|
63
86
|
|
|
87
|
+
Tagging happens from the main checkout (NOT the release worktree),
|
|
88
|
+
because the merged commit lives on `main`:
|
|
89
|
+
|
|
64
90
|
```bash
|
|
65
|
-
|
|
91
|
+
cd "$RELEASE_MAIN"
|
|
92
|
+
git checkout main
|
|
93
|
+
git pull --ff-only origin main
|
|
66
94
|
git tag -a vX.Y.Z -m "Version X.Y.Z"
|
|
67
95
|
git push origin vX.Y.Z
|
|
68
96
|
```
|
|
69
97
|
|
|
70
98
|
Do **not** sign the tag (`-s` flag omitted).
|
|
71
99
|
|
|
100
|
+
After tagging, remove the release worktree -- the branch was already
|
|
101
|
+
deleted by `gh pr merge --delete-branch`:
|
|
102
|
+
```bash
|
|
103
|
+
git -C "$RELEASE_MAIN" worktree remove "$RELEASE_WT" --force
|
|
104
|
+
```
|
|
105
|
+
|
|
72
106
|
## Step 8 -- Create a GitHub release
|
|
73
107
|
|
|
74
108
|
```bash
|
|
@@ -20,8 +20,71 @@ NumPy, Dask, CuPy, and Numba. The prompt is: $ARGUMENTS
|
|
|
20
20
|
```bash
|
|
21
21
|
gh pr diff <number>
|
|
22
22
|
```
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
|
|
24
|
+
## Step 1.5 -- Materialize the PR in a worktree
|
|
25
|
+
|
|
26
|
+
The user's main checkout MUST stay on `main`. Read the PR's files
|
|
27
|
+
from a worktree on the PR's head branch so the review sees the
|
|
28
|
+
actual PR state, not whatever happens to be checked out in the
|
|
29
|
+
main directory.
|
|
30
|
+
|
|
31
|
+
First, detect whether we are already inside a worktree on the PR's
|
|
32
|
+
head branch (this is the common case when `/review-pr` is invoked
|
|
33
|
+
from `/rockout` Step 9):
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
REVIEW_PR_NUM=<number>
|
|
37
|
+
REVIEW_HEAD_BRANCH="$(gh pr view "$REVIEW_PR_NUM" --json headRefName -q .headRefName)"
|
|
38
|
+
REVIEW_CUR_BRANCH="$(git branch --show-current)"
|
|
39
|
+
REVIEW_CUR_TOP="$(git rev-parse --show-toplevel)"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
- If `$REVIEW_CUR_BRANCH` equals `$REVIEW_HEAD_BRANCH` AND
|
|
43
|
+
`$REVIEW_CUR_TOP` contains the segment `.claude/worktrees/`,
|
|
44
|
+
we are already in the right worktree. Set
|
|
45
|
+
`REVIEW_WT="$REVIEW_CUR_TOP"` and skip to step 4 below. Do NOT
|
|
46
|
+
create another worktree -- a second `git worktree add` on the
|
|
47
|
+
same branch will fail.
|
|
48
|
+
|
|
49
|
+
- Otherwise, create a dedicated review worktree:
|
|
50
|
+
|
|
51
|
+
1. From any path, resolve the main checkout (use `--git-common-dir`
|
|
52
|
+
to find the shared repo even if we are inside another worktree):
|
|
53
|
+
```bash
|
|
54
|
+
REVIEW_MAIN="$(git rev-parse --path-format=absolute --git-common-dir)"
|
|
55
|
+
REVIEW_MAIN="${REVIEW_MAIN%/.git}"
|
|
56
|
+
git -C "$REVIEW_MAIN" fetch origin "pull/$REVIEW_PR_NUM/head:pr-$REVIEW_PR_NUM-review"
|
|
57
|
+
git -C "$REVIEW_MAIN" worktree add \
|
|
58
|
+
".claude/worktrees/pr-$REVIEW_PR_NUM-review" "pr-$REVIEW_PR_NUM-review"
|
|
59
|
+
REVIEW_WT="$REVIEW_MAIN/.claude/worktrees/pr-$REVIEW_PR_NUM-review"
|
|
60
|
+
REVIEW_WT_CREATED=1
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
2. Verify isolation -- assert ALL of the following. If any fails,
|
|
64
|
+
STOP and report it:
|
|
65
|
+
- `$REVIEW_WT` exists and is NOT equal to `$REVIEW_MAIN`.
|
|
66
|
+
- `git -C "$REVIEW_WT" branch --show-current` is
|
|
67
|
+
`pr-$REVIEW_PR_NUM-review`.
|
|
68
|
+
- `git -C "$REVIEW_MAIN" branch --show-current` is still
|
|
69
|
+
`main` (or `master`).
|
|
70
|
+
|
|
71
|
+
3. `cd "$REVIEW_WT"` so subsequent reads happen inside the worktree.
|
|
72
|
+
|
|
73
|
+
4. Read every changed file in full (not just the diff) from
|
|
74
|
+
`$REVIEW_WT`. Use paths anchored at `$REVIEW_WT` for all Read
|
|
75
|
+
tool calls -- never read the same file from the main checkout;
|
|
76
|
+
that path reflects `main` and will mislead the review.
|
|
77
|
+
|
|
78
|
+
5. The review is read-only -- do NOT make commits in this worktree.
|
|
79
|
+
When the review is done (after Step 8), clean up only if Step
|
|
80
|
+
1.5 created the worktree:
|
|
81
|
+
```bash
|
|
82
|
+
if [ "${REVIEW_WT_CREATED:-0}" = "1" ]; then
|
|
83
|
+
cd "$REVIEW_MAIN"
|
|
84
|
+
git worktree remove ".claude/worktrees/pr-$REVIEW_PR_NUM-review"
|
|
85
|
+
git branch -D "pr-$REVIEW_PR_NUM-review"
|
|
86
|
+
fi
|
|
87
|
+
```
|
|
25
88
|
|
|
26
89
|
## Step 2 -- Correctness review
|
|
27
90
|
|