argleton 0.1.0__tar.gz → 0.3.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.
Files changed (209) hide show
  1. {argleton-0.1.0 → argleton-0.3.0}/.github/workflows/ci.yml +81 -81
  2. {argleton-0.1.0 → argleton-0.3.0}/CITATION.cff +17 -15
  3. {argleton-0.1.0 → argleton-0.3.0}/PKG-INFO +26 -13
  4. {argleton-0.1.0 → argleton-0.3.0}/README.md +252 -239
  5. {argleton-0.1.0 → argleton-0.3.0}/adapters/engine_geopandas.py +233 -172
  6. {argleton-0.1.0 → argleton-0.3.0}/adapters/engine_naive.py +38 -0
  7. {argleton-0.1.0 → argleton-0.3.0}/adapters/gis_mcp.py +28 -0
  8. {argleton-0.1.0 → argleton-0.3.0}/adapters/mapsmith.py +81 -0
  9. {argleton-0.1.0 → argleton-0.3.0}/argleton/model.py +213 -202
  10. {argleton-0.1.0 → argleton-0.3.0}/argleton/run.py +198 -170
  11. {argleton-0.1.0 → argleton-0.3.0}/argleton/score.py +211 -150
  12. argleton-0.3.0/clean/c022-two-gauges/build.py +48 -0
  13. argleton-0.3.0/clean/c022-two-gauges/probe.toml +41 -0
  14. argleton-0.3.0/clean/c023-longitude-first/build.py +44 -0
  15. argleton-0.3.0/clean/c023-longitude-first/probe.toml +43 -0
  16. {argleton-0.1.0 → argleton-0.3.0}/docs/FAMILIES.md +6 -4
  17. {argleton-0.1.0 → argleton-0.3.0}/docs/METHOD.md +209 -166
  18. {argleton-0.1.0 → argleton-0.3.0}/pyproject.toml +68 -68
  19. argleton-0.3.0/results/2026-08-28-thiessen-pairing/adapters-geopandas.json +452 -0
  20. argleton-0.3.0/results/2026-08-28-thiessen-pairing/adapters-mapsmith.json +451 -0
  21. argleton-0.3.0/results/2026-08-28-thiessen-pairing/adapters-naive.json +451 -0
  22. argleton-0.3.0/results/2026-08-28-thiessen-pairing/adapters-rasterio.json +451 -0
  23. argleton-0.3.0/results/2026-08-28-thiessen-pairing/adapters-whitebox.json +452 -0
  24. argleton-0.3.0/results/2026-08-28-timings/adapters-geopandas.json +551 -0
  25. argleton-0.3.0/results/2026-08-28-timings/adapters-mapsmith.json +550 -0
  26. argleton-0.3.0/results/2026-08-28-timings/adapters-naive.json +550 -0
  27. argleton-0.3.0/results/2026-08-28-timings/adapters-rasterio.json +550 -0
  28. argleton-0.3.0/results/2026-08-28-timings/adapters-whitebox.json +551 -0
  29. argleton-0.3.0/results/2026-08-29-axis-order/adapters-geopandas.json +575 -0
  30. argleton-0.3.0/results/2026-08-29-axis-order/adapters-mapsmith.json +574 -0
  31. argleton-0.3.0/results/2026-08-29-axis-order/adapters-naive.json +574 -0
  32. argleton-0.3.0/results/2026-08-29-axis-order/adapters-rasterio.json +574 -0
  33. argleton-0.3.0/results/2026-08-29-axis-order/adapters-whitebox.json +575 -0
  34. argleton-0.3.0/results/LATEST +1 -0
  35. {argleton-0.1.0 → argleton-0.3.0}/results/README.md +158 -4
  36. argleton-0.3.0/schema/result.schema.json +244 -0
  37. {argleton-0.1.0 → argleton-0.3.0}/site/build.py +246 -221
  38. {argleton-0.1.0 → argleton-0.3.0}/site/index.template.html +366 -342
  39. {argleton-0.1.0 → argleton-0.3.0}/tests/test_showcase.py +458 -350
  40. argleton-0.3.0/traps/022-thiessen-pairing/README.md +114 -0
  41. argleton-0.3.0/traps/022-thiessen-pairing/build.py +67 -0
  42. argleton-0.3.0/traps/022-thiessen-pairing/probe.toml +94 -0
  43. argleton-0.3.0/traps/023-axis-order/README.md +130 -0
  44. argleton-0.3.0/traps/023-axis-order/build.py +57 -0
  45. argleton-0.3.0/traps/023-axis-order/probe.toml +110 -0
  46. argleton-0.1.0/results/LATEST +0 -1
  47. argleton-0.1.0/schema/result.schema.json +0 -103
  48. {argleton-0.1.0 → argleton-0.3.0}/.gitattributes +0 -0
  49. {argleton-0.1.0 → argleton-0.3.0}/.github/workflows/pages.yml +0 -0
  50. {argleton-0.1.0 → argleton-0.3.0}/.gitignore +0 -0
  51. {argleton-0.1.0 → argleton-0.3.0}/LICENSE +0 -0
  52. {argleton-0.1.0 → argleton-0.3.0}/adapters/__init__.py +0 -0
  53. {argleton-0.1.0 → argleton-0.3.0}/adapters/engine_rasterio.py +0 -0
  54. {argleton-0.1.0 → argleton-0.3.0}/adapters/engine_whitebox.py +0 -0
  55. {argleton-0.1.0 → argleton-0.3.0}/argleton/__init__.py +0 -0
  56. {argleton-0.1.0 → argleton-0.3.0}/argleton/published.py +0 -0
  57. {argleton-0.1.0 → argleton-0.3.0}/clean/c001-raster-mean/build.py +0 -0
  58. {argleton-0.1.0 → argleton-0.3.0}/clean/c001-raster-mean/probe.toml +0 -0
  59. {argleton-0.1.0 → argleton-0.3.0}/clean/c002-projected-area/build.py +0 -0
  60. {argleton-0.1.0 → argleton-0.3.0}/clean/c002-projected-area/probe.toml +0 -0
  61. {argleton-0.1.0 → argleton-0.3.0}/clean/c003-raster-mean-nodata/build.py +0 -0
  62. {argleton-0.1.0 → argleton-0.3.0}/clean/c003-raster-mean-nodata/probe.toml +0 -0
  63. {argleton-0.1.0 → argleton-0.3.0}/clean/c004-points-in-polygon/build.py +0 -0
  64. {argleton-0.1.0 → argleton-0.3.0}/clean/c004-points-in-polygon/probe.toml +0 -0
  65. {argleton-0.1.0 → argleton-0.3.0}/clean/c005-polygon-area/build.py +0 -0
  66. {argleton-0.1.0 → argleton-0.3.0}/clean/c005-polygon-area/probe.toml +0 -0
  67. {argleton-0.1.0 → argleton-0.3.0}/clean/c006-named-layer/build.py +0 -0
  68. {argleton-0.1.0 → argleton-0.3.0}/clean/c006-named-layer/probe.toml +0 -0
  69. {argleton-0.1.0 → argleton-0.3.0}/clean/c007-distance-in-metres/build.py +0 -0
  70. {argleton-0.1.0 → argleton-0.3.0}/clean/c007-distance-in-metres/probe.toml +0 -0
  71. {argleton-0.1.0 → argleton-0.3.0}/clean/c008-equal-area-crs/build.py +0 -0
  72. {argleton-0.1.0 → argleton-0.3.0}/clean/c008-equal-area-crs/probe.toml +0 -0
  73. {argleton-0.1.0 → argleton-0.3.0}/clean/c009-native-resolution-classes/build.py +0 -0
  74. {argleton-0.1.0 → argleton-0.3.0}/clean/c009-native-resolution-classes/probe.toml +0 -0
  75. {argleton-0.1.0 → argleton-0.3.0}/clean/c010-physical-values/build.py +0 -0
  76. {argleton-0.1.0 → argleton-0.3.0}/clean/c010-physical-values/probe.toml +0 -0
  77. {argleton-0.1.0 → argleton-0.3.0}/clean/c011-solid-parcel/build.py +0 -0
  78. {argleton-0.1.0 → argleton-0.3.0}/clean/c011-solid-parcel/probe.toml +0 -0
  79. {argleton-0.1.0 → argleton-0.3.0}/clean/c012-disjoint-concessions/build.py +0 -0
  80. {argleton-0.1.0 → argleton-0.3.0}/clean/c012-disjoint-concessions/probe.toml +0 -0
  81. {argleton-0.1.0 → argleton-0.3.0}/clean/c013-flat-pipeline/build.py +0 -0
  82. {argleton-0.1.0 → argleton-0.3.0}/clean/c013-flat-pipeline/probe.toml +0 -0
  83. {argleton-0.1.0 → argleton-0.3.0}/clean/c014-convex-parcel/build.py +0 -0
  84. {argleton-0.1.0 → argleton-0.3.0}/clean/c014-convex-parcel/probe.toml +0 -0
  85. {argleton-0.1.0 → argleton-0.3.0}/clean/c015-wells-off-the-seam/build.py +0 -0
  86. {argleton-0.1.0 → argleton-0.3.0}/clean/c015-wells-off-the-seam/probe.toml +0 -0
  87. {argleton-0.1.0 → argleton-0.3.0}/clean/c016-decimal-degrees/build.py +0 -0
  88. {argleton-0.1.0 → argleton-0.3.0}/clean/c016-decimal-degrees/probe.toml +0 -0
  89. {argleton-0.1.0 → argleton-0.3.0}/clean/c017-equal-populations/build.py +0 -0
  90. {argleton-0.1.0 → argleton-0.3.0}/clean/c017-equal-populations/probe.toml +0 -0
  91. {argleton-0.1.0 → argleton-0.3.0}/clean/c018-plain-keys/build.py +0 -0
  92. {argleton-0.1.0 → argleton-0.3.0}/clean/c018-plain-keys/probe.toml +0 -0
  93. {argleton-0.1.0 → argleton-0.3.0}/clean/c019-fully-contained/build.py +0 -0
  94. {argleton-0.1.0 → argleton-0.3.0}/clean/c019-fully-contained/probe.toml +0 -0
  95. {argleton-0.1.0 → argleton-0.3.0}/clean/c020-one-owner-each/build.py +0 -0
  96. {argleton-0.1.0 → argleton-0.3.0}/clean/c020-one-owner-each/probe.toml +0 -0
  97. {argleton-0.1.0 → argleton-0.3.0}/clean/c021-greenwich-variant/build.py +0 -0
  98. {argleton-0.1.0 → argleton-0.3.0}/clean/c021-greenwich-variant/probe.toml +0 -0
  99. {argleton-0.1.0 → argleton-0.3.0}/docs/ADDING-A-TRAP.md +0 -0
  100. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-23-first-run/adapters-mapsmith.json +0 -0
  101. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-23-first-run/engine-geopandas.json +0 -0
  102. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-23-first-run/engine-naive.json +0 -0
  103. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-23-first-run/engine-rasterio.json +0 -0
  104. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-23-first-run/engine-whitebox.json +0 -0
  105. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-24-five-families/adapters-mapsmith.json +0 -0
  106. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-24-five-families/engine-geopandas.json +0 -0
  107. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-24-five-families/engine-naive.json +0 -0
  108. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-24-five-families/engine-rasterio.json +0 -0
  109. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-24-five-families/engine-whitebox.json +0 -0
  110. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-25-eight-families/adapters-mapsmith.json +0 -0
  111. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-25-eight-families/engine-geopandas.json +0 -0
  112. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-25-eight-families/engine-naive.json +0 -0
  113. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-25-eight-families/engine-rasterio.json +0 -0
  114. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-25-eight-families/engine-whitebox.json +0 -0
  115. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-25-six-families/adapters-mapsmith.json +0 -0
  116. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-25-six-families/engine-geopandas.json +0 -0
  117. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-25-six-families/engine-naive.json +0 -0
  118. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-25-six-families/engine-rasterio.json +0 -0
  119. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-25-six-families/engine-whitebox.json +0 -0
  120. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-26-eighteen-families/adapters-geopandas.json +0 -0
  121. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-26-eighteen-families/adapters-mapsmith.json +0 -0
  122. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-26-eighteen-families/adapters-naive.json +0 -0
  123. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-26-eighteen-families/adapters-rasterio.json +0 -0
  124. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-26-eighteen-families/adapters-whitebox.json +0 -0
  125. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-26-nine-families/adapters-geopandas.json +0 -0
  126. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-26-nine-families/adapters-mapsmith.json +0 -0
  127. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-26-nine-families/adapters-naive.json +0 -0
  128. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-26-nine-families/adapters-rasterio.json +0 -0
  129. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-26-nine-families/adapters-whitebox.json +0 -0
  130. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-26-nineteen-families/adapters-geopandas.json +0 -0
  131. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-26-nineteen-families/adapters-mapsmith.json +0 -0
  132. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-26-nineteen-families/adapters-naive.json +0 -0
  133. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-26-nineteen-families/adapters-rasterio.json +0 -0
  134. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-26-nineteen-families/adapters-whitebox.json +0 -0
  135. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-26-ten-families/adapters-geopandas.json +0 -0
  136. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-26-ten-families/adapters-mapsmith.json +0 -0
  137. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-26-ten-families/adapters-naive.json +0 -0
  138. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-26-ten-families/adapters-rasterio.json +0 -0
  139. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-26-ten-families/adapters-whitebox.json +0 -0
  140. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-27-datum-shift-fixed/adapters-geopandas.json +0 -0
  141. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-27-datum-shift-fixed/adapters-mapsmith.json +0 -0
  142. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-27-datum-shift-fixed/adapters-naive.json +0 -0
  143. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-27-datum-shift-fixed/adapters-rasterio.json +0 -0
  144. {argleton-0.1.0 → argleton-0.3.0}/results/2026-08-27-datum-shift-fixed/adapters-whitebox.json +0 -0
  145. {argleton-0.1.0 → argleton-0.3.0}/schema/probe.schema.json +0 -0
  146. {argleton-0.1.0 → argleton-0.3.0}/tests/test_contracts.py +0 -0
  147. {argleton-0.1.0 → argleton-0.3.0}/traps/001-tiff-predictor/README.md +0 -0
  148. {argleton-0.1.0 → argleton-0.3.0}/traps/001-tiff-predictor/build.py +0 -0
  149. {argleton-0.1.0 → argleton-0.3.0}/traps/001-tiff-predictor/probe.toml +0 -0
  150. {argleton-0.1.0 → argleton-0.3.0}/traps/002-feet-as-metres/README.md +0 -0
  151. {argleton-0.1.0 → argleton-0.3.0}/traps/002-feet-as-metres/build.py +0 -0
  152. {argleton-0.1.0 → argleton-0.3.0}/traps/002-feet-as-metres/probe.toml +0 -0
  153. {argleton-0.1.0 → argleton-0.3.0}/traps/003-nodata-in-statistics/README.md +0 -0
  154. {argleton-0.1.0 → argleton-0.3.0}/traps/003-nodata-in-statistics/build.py +0 -0
  155. {argleton-0.1.0 → argleton-0.3.0}/traps/003-nodata-in-statistics/probe.toml +0 -0
  156. {argleton-0.1.0 → argleton-0.3.0}/traps/004-mismatched-crs-join/README.md +0 -0
  157. {argleton-0.1.0 → argleton-0.3.0}/traps/004-mismatched-crs-join/build.py +0 -0
  158. {argleton-0.1.0 → argleton-0.3.0}/traps/004-mismatched-crs-join/probe.toml +0 -0
  159. {argleton-0.1.0 → argleton-0.3.0}/traps/005-bowtie-area/README.md +0 -0
  160. {argleton-0.1.0 → argleton-0.3.0}/traps/005-bowtie-area/build.py +0 -0
  161. {argleton-0.1.0 → argleton-0.3.0}/traps/005-bowtie-area/probe.toml +0 -0
  162. {argleton-0.1.0 → argleton-0.3.0}/traps/006-default-layer/README.md +0 -0
  163. {argleton-0.1.0 → argleton-0.3.0}/traps/006-default-layer/build.py +0 -0
  164. {argleton-0.1.0 → argleton-0.3.0}/traps/006-default-layer/probe.toml +0 -0
  165. {argleton-0.1.0 → argleton-0.3.0}/traps/007-buffer-in-degrees/README.md +0 -0
  166. {argleton-0.1.0 → argleton-0.3.0}/traps/007-buffer-in-degrees/build.py +0 -0
  167. {argleton-0.1.0 → argleton-0.3.0}/traps/007-buffer-in-degrees/probe.toml +0 -0
  168. {argleton-0.1.0 → argleton-0.3.0}/traps/008-web-mercator-area/README.md +0 -0
  169. {argleton-0.1.0 → argleton-0.3.0}/traps/008-web-mercator-area/build.py +0 -0
  170. {argleton-0.1.0 → argleton-0.3.0}/traps/008-web-mercator-area/probe.toml +0 -0
  171. {argleton-0.1.0 → argleton-0.3.0}/traps/009-resampled-classes/README.md +0 -0
  172. {argleton-0.1.0 → argleton-0.3.0}/traps/009-resampled-classes/build.py +0 -0
  173. {argleton-0.1.0 → argleton-0.3.0}/traps/009-resampled-classes/probe.toml +0 -0
  174. {argleton-0.1.0 → argleton-0.3.0}/traps/010-scale-offset/README.md +0 -0
  175. {argleton-0.1.0 → argleton-0.3.0}/traps/010-scale-offset/build.py +0 -0
  176. {argleton-0.1.0 → argleton-0.3.0}/traps/010-scale-offset/probe.toml +0 -0
  177. {argleton-0.1.0 → argleton-0.3.0}/traps/011-polygon-holes/README.md +0 -0
  178. {argleton-0.1.0 → argleton-0.3.0}/traps/011-polygon-holes/build.py +0 -0
  179. {argleton-0.1.0 → argleton-0.3.0}/traps/011-polygon-holes/probe.toml +0 -0
  180. {argleton-0.1.0 → argleton-0.3.0}/traps/012-double-counting/README.md +0 -0
  181. {argleton-0.1.0 → argleton-0.3.0}/traps/012-double-counting/build.py +0 -0
  182. {argleton-0.1.0 → argleton-0.3.0}/traps/012-double-counting/probe.toml +0 -0
  183. {argleton-0.1.0 → argleton-0.3.0}/traps/013-z-dimension/README.md +0 -0
  184. {argleton-0.1.0 → argleton-0.3.0}/traps/013-z-dimension/build.py +0 -0
  185. {argleton-0.1.0 → argleton-0.3.0}/traps/013-z-dimension/probe.toml +0 -0
  186. {argleton-0.1.0 → argleton-0.3.0}/traps/014-centroid-outside/README.md +0 -0
  187. {argleton-0.1.0 → argleton-0.3.0}/traps/014-centroid-outside/build.py +0 -0
  188. {argleton-0.1.0 → argleton-0.3.0}/traps/014-centroid-outside/probe.toml +0 -0
  189. {argleton-0.1.0 → argleton-0.3.0}/traps/015-boundary-semantics/README.md +0 -0
  190. {argleton-0.1.0 → argleton-0.3.0}/traps/015-boundary-semantics/build.py +0 -0
  191. {argleton-0.1.0 → argleton-0.3.0}/traps/015-boundary-semantics/probe.toml +0 -0
  192. {argleton-0.1.0 → argleton-0.3.0}/traps/016-coordinate-parsing/README.md +0 -0
  193. {argleton-0.1.0 → argleton-0.3.0}/traps/016-coordinate-parsing/build.py +0 -0
  194. {argleton-0.1.0 → argleton-0.3.0}/traps/016-coordinate-parsing/probe.toml +0 -0
  195. {argleton-0.1.0 → argleton-0.3.0}/traps/017-aggregation-weighting/README.md +0 -0
  196. {argleton-0.1.0 → argleton-0.3.0}/traps/017-aggregation-weighting/build.py +0 -0
  197. {argleton-0.1.0 → argleton-0.3.0}/traps/017-aggregation-weighting/probe.toml +0 -0
  198. {argleton-0.1.0 → argleton-0.3.0}/traps/018-join-key-typing/README.md +0 -0
  199. {argleton-0.1.0 → argleton-0.3.0}/traps/018-join-key-typing/build.py +0 -0
  200. {argleton-0.1.0 → argleton-0.3.0}/traps/018-join-key-typing/probe.toml +0 -0
  201. {argleton-0.1.0 → argleton-0.3.0}/traps/019-partial-overlap/README.md +0 -0
  202. {argleton-0.1.0 → argleton-0.3.0}/traps/019-partial-overlap/build.py +0 -0
  203. {argleton-0.1.0 → argleton-0.3.0}/traps/019-partial-overlap/probe.toml +0 -0
  204. {argleton-0.1.0 → argleton-0.3.0}/traps/020-join-cardinality/README.md +0 -0
  205. {argleton-0.1.0 → argleton-0.3.0}/traps/020-join-cardinality/build.py +0 -0
  206. {argleton-0.1.0 → argleton-0.3.0}/traps/020-join-cardinality/probe.toml +0 -0
  207. {argleton-0.1.0 → argleton-0.3.0}/traps/021-ballpark-datum/README.md +0 -0
  208. {argleton-0.1.0 → argleton-0.3.0}/traps/021-ballpark-datum/build.py +0 -0
  209. {argleton-0.1.0 → argleton-0.3.0}/traps/021-ballpark-datum/probe.toml +0 -0
@@ -1,81 +1,81 @@
1
- name: CI
2
-
3
- on:
4
- push:
5
- branches: [main]
6
- pull_request:
7
-
8
- permissions:
9
- contents: read
10
-
11
- jobs:
12
- suite:
13
- runs-on: ubuntu-latest
14
- strategy:
15
- matrix:
16
- python: ["3.11", "3.13"]
17
- steps:
18
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
19
- - uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0
20
- with:
21
- python-version: ${{ matrix.python }}
22
- - run: pip install -e .[fixtures,whitebox,geopandas,dev]
23
- - run: pip install ruff==0.16.3
24
- - run: ruff check .
25
- - run: pytest -q
26
- # The engine tier is deterministic and free, so it runs on every commit.
27
- # rasterio must stay at zero silent errors; whitebox is expected to fail
28
- # trap 001 until upstream fixes it, which is why the run is not gated on
29
- # the rate — a red build for a defect in someone else's library would
30
- # train us to ignore the build.
31
- - run: argleton --adapter engine:rasterio --out /tmp/rasterio.json
32
- - run: argleton --adapter engine:geopandas --out /tmp/geopandas.json
33
- - run: argleton --adapter engine:whitebox --out /tmp/whitebox.json
34
- - run: argleton --adapter engine:naive --out /tmp/naive.json
35
- # The careful adapters must stay at zero. "Careful" is not a compliment
36
- # about the library: `engine:rasterio` and `engine:geopandas` compose those
37
- # libraries the way a caller who knows them does — unit read from the CRS,
38
- # geographic CRS refused for a planar area, invalid ring repaired and the
39
- # repair disclosed, a ballpark transformation detected. `engine:naive` is
40
- # the same libraries composed the way almost everyone writes first, and the
41
- # gap between the two rows is what this suite is for.
42
- #
43
- # The other two are expected to fail their traps — one because of a defect
44
- # in someone else's library, one because it is the careless composition on
45
- # purpose — so the build is not gated on them. A red build for a known
46
- # upstream bug would train us to ignore the build, which costs more than
47
- # the signal is worth.
48
- #
49
- # This gate went red on 2026-08-26 for a good reason: `engine:geopandas`
50
- # had one operation doing the ordinary thing while its other nine did the
51
- # careful thing, so it was no longer the adapter this gate describes. The
52
- # answer was to make the adapter consistent again AND to fix the label on
53
- # the published table, which is what had been misleading.
54
- - name: the careful adapters must have no silent errors
55
- run: |
56
- python - <<'PY'
57
- import json, sys
58
- bad = []
59
- for name in ("rasterio", "geopandas"):
60
- r = json.load(open(f"/tmp/{name}.json"))
61
- print(name, r["silent_error_rate"], r["completion_rate"])
62
- if r["silent_error_rate"] != 0.0 or r["completion_rate"] != 1.0:
63
- bad.append(name)
64
- sys.exit(1 if bad else 0)
65
- PY
66
- # And the ones that are supposed to fail must still fail: a trap that
67
- # stops catching its own naive adapter has quietly stopped measuring.
68
- - name: the naive adapter must still fall into its trap
69
- run: |
70
- python - <<'PY'
71
- import json, sys
72
- r = json.load(open("/tmp/naive.json"))
73
- print(r["silent_error_rate"], r["completion_rate"])
74
- # Not 1.0: the careless composition is correct on trap 001, because
75
- # rasterio undoes the predictor for it. Pinning the exact rate is the
76
- # point — a trap that stops catching its own naive adapter, or one
77
- # that starts catching a case it should not, has changed what it
78
- # measures, and that must be a decision rather than a surprise.
79
- # 0.9524 = traps 002 through 021 caught, 001 passed, out of 21.
80
- sys.exit(0 if (r["silent_error_rate"], r["completion_rate"]) == (0.9524, 1.0) else 1)
81
- PY
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ suite:
13
+ runs-on: ubuntu-latest
14
+ strategy:
15
+ matrix:
16
+ python: ["3.11", "3.13"]
17
+ steps:
18
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
19
+ - uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0
20
+ with:
21
+ python-version: ${{ matrix.python }}
22
+ - run: pip install -e .[fixtures,whitebox,geopandas,dev]
23
+ - run: pip install ruff==0.16.3
24
+ - run: ruff check .
25
+ - run: pytest -q
26
+ # The engine tier is deterministic and free, so it runs on every commit.
27
+ # rasterio must stay at zero silent errors; whitebox is expected to fail
28
+ # trap 001 until upstream fixes it, which is why the run is not gated on
29
+ # the rate — a red build for a defect in someone else's library would
30
+ # train us to ignore the build.
31
+ - run: argleton --adapter engine:rasterio --out /tmp/rasterio.json
32
+ - run: argleton --adapter engine:geopandas --out /tmp/geopandas.json
33
+ - run: argleton --adapter engine:whitebox --out /tmp/whitebox.json
34
+ - run: argleton --adapter engine:naive --out /tmp/naive.json
35
+ # The careful adapters must stay at zero. "Careful" is not a compliment
36
+ # about the library: `engine:rasterio` and `engine:geopandas` compose those
37
+ # libraries the way a caller who knows them does — unit read from the CRS,
38
+ # geographic CRS refused for a planar area, invalid ring repaired and the
39
+ # repair disclosed, a ballpark transformation detected. `engine:naive` is
40
+ # the same libraries composed the way almost everyone writes first, and the
41
+ # gap between the two rows is what this suite is for.
42
+ #
43
+ # The other two are expected to fail their traps — one because of a defect
44
+ # in someone else's library, one because it is the careless composition on
45
+ # purpose — so the build is not gated on them. A red build for a known
46
+ # upstream bug would train us to ignore the build, which costs more than
47
+ # the signal is worth.
48
+ #
49
+ # This gate went red on 2026-08-26 for a good reason: `engine:geopandas`
50
+ # had one operation doing the ordinary thing while its other nine did the
51
+ # careful thing, so it was no longer the adapter this gate describes. The
52
+ # answer was to make the adapter consistent again AND to fix the label on
53
+ # the published table, which is what had been misleading.
54
+ - name: the careful adapters must have no silent errors
55
+ run: |
56
+ python - <<'PY'
57
+ import json, sys
58
+ bad = []
59
+ for name in ("rasterio", "geopandas"):
60
+ r = json.load(open(f"/tmp/{name}.json"))
61
+ print(name, r["silent_error_rate"], r["completion_rate"])
62
+ if r["silent_error_rate"] != 0.0 or r["completion_rate"] != 1.0:
63
+ bad.append(name)
64
+ sys.exit(1 if bad else 0)
65
+ PY
66
+ # And the ones that are supposed to fail must still fail: a trap that
67
+ # stops catching its own naive adapter has quietly stopped measuring.
68
+ - name: the naive adapter must still fall into its trap
69
+ run: |
70
+ python - <<'PY'
71
+ import json, sys
72
+ r = json.load(open("/tmp/naive.json"))
73
+ print(r["silent_error_rate"], r["completion_rate"])
74
+ # Not 1.0: the careless composition is correct on trap 001, because
75
+ # rasterio undoes the predictor for it. Pinning the exact rate is the
76
+ # point — a trap that stops catching its own naive adapter, or one
77
+ # that starts catching a case it should not, has changed what it
78
+ # measures, and that must be a decision rather than a surprise.
79
+ # 0.9545 = traps 002 through 022 caught, 001 passed, out of 22.
80
+ sys.exit(0 if (r["silent_error_rate"], r["completion_rate"]) == (0.9545, 1.0) else 1)
81
+ PY
@@ -1,15 +1,17 @@
1
- cff-version: 1.2.0
2
- message: "If you use Argleton in your work, please cite it as below."
3
- title: "Argleton: a correctness suite for geospatial systems"
4
- type: software
5
- authors:
6
- - name: "The Argleton project"
7
- repository-code: "https://github.com/argleton/argleton"
8
- url: "https://argleton.org"
9
- license: Apache-2.0
10
- abstract: >-
11
- Probes whose right answer is known by construction — derived on paper, never
12
- measured from a reference implementation — and whose typical wrong answer
13
- looks fine. Argleton measures the silent-error rate of geospatial systems
14
- alongside their completion rate on defect-free twins, so that a score cannot
15
- be gamed by refusing to answer.
1
+ cff-version: 1.2.0
2
+ message: "If you use Argleton in your work, please cite it as below."
3
+ title: "Argleton: a correctness suite for geospatial systems"
4
+ type: software
5
+ authors:
6
+ - name: "The Argleton project"
7
+ repository-code: "https://github.com/argleton/argleton"
8
+ url: "https://argleton.org"
9
+ license: Apache-2.0
10
+ version: "0.3.0"
11
+ date-released: "2026-08-29"
12
+ abstract: >-
13
+ Probes whose right answer is known by construction — derived on paper, never
14
+ measured from a reference implementation — and whose typical wrong answer
15
+ looks fine. Argleton measures the silent-error rate of geospatial systems
16
+ alongside their completion rate on defect-free twins, so that a score cannot
17
+ be gamed by refusing to answer.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: argleton
3
- Version: 0.1.0
3
+ Version: 0.3.0
4
4
  Summary: Probes whose right answer is known by construction, and whose wrong answer looks fine
5
5
  Project-URL: Source, https://github.com/argleton/argleton
6
6
  Author: Argleton contributors
@@ -60,9 +60,20 @@ ordinary elevations. The raster still renders as terrain, hillshade still looks
60
60
  like hillshade, flow accumulation still flows downhill. Nothing anywhere says
61
61
  anything is wrong.
62
62
 
63
- Seeing it needs a checkout and one install — every fixture is rebuilt
64
- deterministically on your machine, so there is nothing to download and nothing
65
- to take on trust:
63
+ Seeing it needs one install — every fixture is rebuilt deterministically on your
64
+ machine, so there is nothing to download and nothing to take on trust:
65
+
66
+ ```
67
+ pip install "argleton[fixtures]"
68
+ ```
69
+
70
+ The probes ship with the runner, so that is the whole setup — release 0.3.0 carries the
71
+ 23 traps and 26 families the results below were produced from. When the checkout runs ahead
72
+ of the release this paragraph says so, because a reader who cannot reproduce the table on
73
+ this page has been told something untrue.
74
+
75
+ To read the probes, change them, or add one, take the checkout instead — the probes are the point of the
76
+ repository and `probe.toml` is meant to be read:
66
77
 
67
78
  ```
68
79
  git clone https://github.com/argleton/argleton
@@ -98,8 +109,8 @@ every task it was given (completion 1.0) *and* gets this file silently wrong
98
109
  (the 0.5).
99
110
 
100
111
  There is a third adapter, `engine:naive` — read the file, take the statistic,
101
- report it — and it is the most useful one here. It scores **0.9524 / 1.0**: it
102
- answers every clean probe correctly, falls into twenty of the twenty-one traps, and
112
+ report it — and it is the most useful one here. It scores **0.9565 / 1.0**: it
113
+ answers every clean probe correctly, falls into twenty-two of the twenty-three traps, and
103
114
  **passes the remaining one**, because rasterio undoes the predictor on its
104
115
  behalf. Careless code is not uniformly wrong. It is correct until the data stops
105
116
  having the shape it usually has, which is what makes the exceptions so hard to
@@ -123,7 +134,7 @@ Side by side, one glance tells you which you are looking at.
123
134
 
124
135
  ## What is covered
125
136
 
126
- Nineteen families of twenty-four, and [FAMILIES.md](docs/FAMILIES.md) says which — so a
137
+ Twenty-one families of twenty-six, and [FAMILIES.md](docs/FAMILIES.md) says which — so a
127
138
  number from here can never be read as broader than it is. A low silent-error
128
139
  rate means a system did not fail silently *on these probes*.
129
140
 
@@ -148,19 +159,21 @@ rate means a system did not fail silently *on these probes*.
148
159
  | `coordinate-parsing` | 41.5324 instead of 41.89 | both are latitudes in central Italy, 40 km apart |
149
160
  | `aggregation-weighting` | 13.67% instead of 1.38% | averaging rates treats a village as equal to a city |
150
161
  | `tabular-join` | 62000 people instead of 100000 | a CSV reader turns "001" into 1 and four municipalities leave the join |
162
+ | `positional-pairing` | 554 mm of rainfall instead of 268 | the Thiessen cells are all valid and tile the extent; only the row each one carries is wrong |
163
+ | `axis-order` | 16261 m² instead of 14042 | EPSG:4326 declares latitude first and every geometry library expects longitude first; both readings of a corner schedule stay in range |
151
164
 
152
165
  ## Results
153
166
 
154
- Engine tier, nineteen families, `spec_commit` pinned — [every run, and what the
167
+ Engine tier, twenty-one families, `spec_commit` pinned — [every run, and what the
155
168
  numbers do not say](results/).
156
169
 
157
170
  | system | silent error rate | completion rate | traps run | not applicable |
158
171
  |---|---|---|---|---|
159
- | MapSmith (main) | 0.00 | 1.00 | 21 | 0 |
160
- | rasterio 1.5.1 (careful composition) | 0.00 | 1.00 | 4 | 34 |
161
- | GeoPandas 1.1 + Shapely 2 (careful composition) | 0.00 | 1.00 | 7 | 28 |
162
- | whitebox-workflows 2.0.6 | 0.50 | 1.00 | 2 | 38 |
163
- | naive composition | 0.9524 | 1.00 | 21 | 0 |
172
+ | MapSmith (main) | 0.00 | 1.00 | 23 | 0 |
173
+ | rasterio 1.5.1 (careful composition) | 0.00 | 1.00 | 4 | 38 |
174
+ | GeoPandas 1.1 + Shapely 2 (careful composition) | 0.00 | 1.00 | 9 | 28 |
175
+ | whitebox-workflows 2.0.6 | 0.50 | 1.00 | 2 | 42 |
176
+ | naive composition | 0.9565 | 1.00 | 23 | 0 |
164
177
 
165
178
  The last two columns are not decoration. A rate over two traps and a rate over
166
179
  eight are different claims, and an adapter that could only be asked one question