argleton 0.5.0__tar.gz → 0.6.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 (307) hide show
  1. {argleton-0.5.0 → argleton-0.6.0}/.github/workflows/ci.yml +11 -6
  2. {argleton-0.5.0 → argleton-0.6.0}/.zenodo.json +1 -1
  3. {argleton-0.5.0 → argleton-0.6.0}/CHANGELOG.md +28 -0
  4. {argleton-0.5.0 → argleton-0.6.0}/CITATION.cff +2 -2
  5. {argleton-0.5.0 → argleton-0.6.0}/PKG-INFO +42 -33
  6. {argleton-0.5.0 → argleton-0.6.0}/README.md +41 -32
  7. {argleton-0.5.0 → argleton-0.6.0}/adapters/engine_rasterio.py +7 -11
  8. {argleton-0.5.0 → argleton-0.6.0}/argleton/model.py +2 -2
  9. {argleton-0.5.0 → argleton-0.6.0}/argleton/run.py +6 -6
  10. {argleton-0.5.0 → argleton-0.6.0}/clean/c024-pixel-is-area/build.py +6 -4
  11. {argleton-0.5.0 → argleton-0.6.0}/clean/c024-pixel-is-area/probe.toml +17 -15
  12. {argleton-0.5.0 → argleton-0.6.0}/docs/FAMILIES.md +2 -2
  13. {argleton-0.5.0 → argleton-0.6.0}/pyproject.toml +1 -1
  14. argleton-0.6.0/results/2026-09-26-trap-024-corrected/adapters-geopandas.json +767 -0
  15. argleton-0.6.0/results/2026-09-26-trap-024-corrected/adapters-gis-mcp.json +767 -0
  16. argleton-0.6.0/results/2026-09-26-trap-024-corrected/adapters-mapsmith.json +767 -0
  17. argleton-0.6.0/results/2026-09-26-trap-024-corrected/adapters-naive.json +766 -0
  18. argleton-0.6.0/results/2026-09-26-trap-024-corrected/adapters-qgis-agent-mcp.json +768 -0
  19. argleton-0.6.0/results/2026-09-26-trap-024-corrected/adapters-qgis-mcp.json +768 -0
  20. argleton-0.6.0/results/2026-09-26-trap-024-corrected/adapters-qgis.json +767 -0
  21. argleton-0.6.0/results/2026-09-26-trap-024-corrected/adapters-rasterio.json +767 -0
  22. argleton-0.6.0/results/2026-09-26-trap-024-corrected/adapters-whitebox.json +767 -0
  23. argleton-0.6.0/results/LATEST +1 -0
  24. {argleton-0.5.0 → argleton-0.6.0}/results/README.md +86 -6
  25. {argleton-0.5.0 → argleton-0.6.0}/site/build.py +656 -390
  26. {argleton-0.5.0 → argleton-0.6.0}/site/index.template.html +388 -383
  27. {argleton-0.5.0 → argleton-0.6.0}/tests/test_showcase.py +181 -30
  28. argleton-0.6.0/tests/test_site_erratum.py +83 -0
  29. argleton-0.6.0/traps/024-pixel-is-point/README.md +121 -0
  30. {argleton-0.5.0 → argleton-0.6.0}/traps/024-pixel-is-point/build.py +13 -8
  31. argleton-0.6.0/traps/024-pixel-is-point/probe.toml +144 -0
  32. argleton-0.5.0/results/LATEST +0 -1
  33. argleton-0.5.0/traps/024-pixel-is-point/README.md +0 -111
  34. argleton-0.5.0/traps/024-pixel-is-point/probe.toml +0 -137
  35. {argleton-0.5.0 → argleton-0.6.0}/.gitattributes +0 -0
  36. {argleton-0.5.0 → argleton-0.6.0}/.github/workflows/pages.yml +0 -0
  37. {argleton-0.5.0 → argleton-0.6.0}/.gitignore +0 -0
  38. {argleton-0.5.0 → argleton-0.6.0}/LICENSE +0 -0
  39. {argleton-0.5.0 → argleton-0.6.0}/adapters/__init__.py +0 -0
  40. {argleton-0.5.0 → argleton-0.6.0}/adapters/engine_geopandas.py +0 -0
  41. {argleton-0.5.0 → argleton-0.6.0}/adapters/engine_naive.py +0 -0
  42. {argleton-0.5.0 → argleton-0.6.0}/adapters/engine_qgis.py +0 -0
  43. {argleton-0.5.0 → argleton-0.6.0}/adapters/engine_whitebox.py +0 -0
  44. {argleton-0.5.0 → argleton-0.6.0}/adapters/gis_mcp.py +0 -0
  45. {argleton-0.5.0 → argleton-0.6.0}/adapters/mapsmith.py +0 -0
  46. {argleton-0.5.0 → argleton-0.6.0}/adapters/qgis_agent_mcp.py +0 -0
  47. {argleton-0.5.0 → argleton-0.6.0}/adapters/qgis_chains.py +0 -0
  48. {argleton-0.5.0 → argleton-0.6.0}/adapters/qgis_mcp_plugin.py +0 -0
  49. {argleton-0.5.0 → argleton-0.6.0}/argleton/__init__.py +0 -0
  50. {argleton-0.5.0 → argleton-0.6.0}/argleton/published.py +0 -0
  51. {argleton-0.5.0 → argleton-0.6.0}/argleton/score.py +0 -0
  52. {argleton-0.5.0 → argleton-0.6.0}/clean/c001-raster-mean/build.py +0 -0
  53. {argleton-0.5.0 → argleton-0.6.0}/clean/c001-raster-mean/probe.toml +0 -0
  54. {argleton-0.5.0 → argleton-0.6.0}/clean/c002-projected-area/build.py +0 -0
  55. {argleton-0.5.0 → argleton-0.6.0}/clean/c002-projected-area/probe.toml +0 -0
  56. {argleton-0.5.0 → argleton-0.6.0}/clean/c003-raster-mean-nodata/build.py +0 -0
  57. {argleton-0.5.0 → argleton-0.6.0}/clean/c003-raster-mean-nodata/probe.toml +0 -0
  58. {argleton-0.5.0 → argleton-0.6.0}/clean/c004-points-in-polygon/build.py +0 -0
  59. {argleton-0.5.0 → argleton-0.6.0}/clean/c004-points-in-polygon/probe.toml +0 -0
  60. {argleton-0.5.0 → argleton-0.6.0}/clean/c005-polygon-area/build.py +0 -0
  61. {argleton-0.5.0 → argleton-0.6.0}/clean/c005-polygon-area/probe.toml +0 -0
  62. {argleton-0.5.0 → argleton-0.6.0}/clean/c006-named-layer/build.py +0 -0
  63. {argleton-0.5.0 → argleton-0.6.0}/clean/c006-named-layer/probe.toml +0 -0
  64. {argleton-0.5.0 → argleton-0.6.0}/clean/c007-distance-in-metres/build.py +0 -0
  65. {argleton-0.5.0 → argleton-0.6.0}/clean/c007-distance-in-metres/probe.toml +0 -0
  66. {argleton-0.5.0 → argleton-0.6.0}/clean/c008-equal-area-crs/build.py +0 -0
  67. {argleton-0.5.0 → argleton-0.6.0}/clean/c008-equal-area-crs/probe.toml +0 -0
  68. {argleton-0.5.0 → argleton-0.6.0}/clean/c009-native-resolution-classes/build.py +0 -0
  69. {argleton-0.5.0 → argleton-0.6.0}/clean/c009-native-resolution-classes/probe.toml +0 -0
  70. {argleton-0.5.0 → argleton-0.6.0}/clean/c010-physical-values/build.py +0 -0
  71. {argleton-0.5.0 → argleton-0.6.0}/clean/c010-physical-values/probe.toml +0 -0
  72. {argleton-0.5.0 → argleton-0.6.0}/clean/c011-solid-parcel/build.py +0 -0
  73. {argleton-0.5.0 → argleton-0.6.0}/clean/c011-solid-parcel/probe.toml +0 -0
  74. {argleton-0.5.0 → argleton-0.6.0}/clean/c012-disjoint-concessions/build.py +0 -0
  75. {argleton-0.5.0 → argleton-0.6.0}/clean/c012-disjoint-concessions/probe.toml +0 -0
  76. {argleton-0.5.0 → argleton-0.6.0}/clean/c013-flat-pipeline/build.py +0 -0
  77. {argleton-0.5.0 → argleton-0.6.0}/clean/c013-flat-pipeline/probe.toml +0 -0
  78. {argleton-0.5.0 → argleton-0.6.0}/clean/c014-convex-parcel/build.py +0 -0
  79. {argleton-0.5.0 → argleton-0.6.0}/clean/c014-convex-parcel/probe.toml +0 -0
  80. {argleton-0.5.0 → argleton-0.6.0}/clean/c015-wells-off-the-seam/build.py +0 -0
  81. {argleton-0.5.0 → argleton-0.6.0}/clean/c015-wells-off-the-seam/probe.toml +0 -0
  82. {argleton-0.5.0 → argleton-0.6.0}/clean/c016-decimal-degrees/build.py +0 -0
  83. {argleton-0.5.0 → argleton-0.6.0}/clean/c016-decimal-degrees/probe.toml +0 -0
  84. {argleton-0.5.0 → argleton-0.6.0}/clean/c017-equal-populations/build.py +0 -0
  85. {argleton-0.5.0 → argleton-0.6.0}/clean/c017-equal-populations/probe.toml +0 -0
  86. {argleton-0.5.0 → argleton-0.6.0}/clean/c018-plain-keys/build.py +0 -0
  87. {argleton-0.5.0 → argleton-0.6.0}/clean/c018-plain-keys/probe.toml +0 -0
  88. {argleton-0.5.0 → argleton-0.6.0}/clean/c019-fully-contained/build.py +0 -0
  89. {argleton-0.5.0 → argleton-0.6.0}/clean/c019-fully-contained/probe.toml +0 -0
  90. {argleton-0.5.0 → argleton-0.6.0}/clean/c020-one-owner-each/build.py +0 -0
  91. {argleton-0.5.0 → argleton-0.6.0}/clean/c020-one-owner-each/probe.toml +0 -0
  92. {argleton-0.5.0 → argleton-0.6.0}/clean/c021-greenwich-variant/build.py +0 -0
  93. {argleton-0.5.0 → argleton-0.6.0}/clean/c021-greenwich-variant/probe.toml +0 -0
  94. {argleton-0.5.0 → argleton-0.6.0}/clean/c022-two-gauges/build.py +0 -0
  95. {argleton-0.5.0 → argleton-0.6.0}/clean/c022-two-gauges/probe.toml +0 -0
  96. {argleton-0.5.0 → argleton-0.6.0}/clean/c023-longitude-first/build.py +0 -0
  97. {argleton-0.5.0 → argleton-0.6.0}/clean/c023-longitude-first/probe.toml +0 -0
  98. {argleton-0.5.0 → argleton-0.6.0}/clean/c025-single-hemisphere-zone/build.py +0 -0
  99. {argleton-0.5.0 → argleton-0.6.0}/clean/c025-single-hemisphere-zone/probe.toml +0 -0
  100. {argleton-0.5.0 → argleton-0.6.0}/clean/c026-north-up-grid/build.py +0 -0
  101. {argleton-0.5.0 → argleton-0.6.0}/clean/c026-north-up-grid/probe.toml +0 -0
  102. {argleton-0.5.0 → argleton-0.6.0}/clean/c027-lines-only/build.py +0 -0
  103. {argleton-0.5.0 → argleton-0.6.0}/clean/c027-lines-only/probe.toml +0 -0
  104. {argleton-0.5.0 → argleton-0.6.0}/clean/c028-projected-field/build.py +0 -0
  105. {argleton-0.5.0 → argleton-0.6.0}/clean/c028-projected-field/probe.toml +0 -0
  106. {argleton-0.5.0 → argleton-0.6.0}/clean/c029-coincident-boundaries/build.py +0 -0
  107. {argleton-0.5.0 → argleton-0.6.0}/clean/c029-coincident-boundaries/probe.toml +0 -0
  108. {argleton-0.5.0 → argleton-0.6.0}/clean/c030-single-georeferencing/build.py +0 -0
  109. {argleton-0.5.0 → argleton-0.6.0}/clean/c030-single-georeferencing/probe.toml +0 -0
  110. {argleton-0.5.0 → argleton-0.6.0}/clean/c031-hole-wound-as-hole/README.md +0 -0
  111. {argleton-0.5.0 → argleton-0.6.0}/clean/c031-hole-wound-as-hole/build.py +0 -0
  112. {argleton-0.5.0 → argleton-0.6.0}/clean/c031-hole-wound-as-hole/probe.toml +0 -0
  113. {argleton-0.5.0 → argleton-0.6.0}/docs/ADDING-A-TRAP.md +0 -0
  114. {argleton-0.5.0 → argleton-0.6.0}/docs/METHOD.md +0 -0
  115. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-23-first-run/adapters-mapsmith.json +0 -0
  116. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-23-first-run/engine-geopandas.json +0 -0
  117. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-23-first-run/engine-naive.json +0 -0
  118. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-23-first-run/engine-rasterio.json +0 -0
  119. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-23-first-run/engine-whitebox.json +0 -0
  120. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-24-five-families/adapters-mapsmith.json +0 -0
  121. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-24-five-families/engine-geopandas.json +0 -0
  122. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-24-five-families/engine-naive.json +0 -0
  123. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-24-five-families/engine-rasterio.json +0 -0
  124. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-24-five-families/engine-whitebox.json +0 -0
  125. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-25-eight-families/adapters-mapsmith.json +0 -0
  126. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-25-eight-families/engine-geopandas.json +0 -0
  127. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-25-eight-families/engine-naive.json +0 -0
  128. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-25-eight-families/engine-rasterio.json +0 -0
  129. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-25-eight-families/engine-whitebox.json +0 -0
  130. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-25-six-families/adapters-mapsmith.json +0 -0
  131. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-25-six-families/engine-geopandas.json +0 -0
  132. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-25-six-families/engine-naive.json +0 -0
  133. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-25-six-families/engine-rasterio.json +0 -0
  134. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-25-six-families/engine-whitebox.json +0 -0
  135. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-26-eighteen-families/adapters-geopandas.json +0 -0
  136. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-26-eighteen-families/adapters-mapsmith.json +0 -0
  137. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-26-eighteen-families/adapters-naive.json +0 -0
  138. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-26-eighteen-families/adapters-rasterio.json +0 -0
  139. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-26-eighteen-families/adapters-whitebox.json +0 -0
  140. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-26-nine-families/adapters-geopandas.json +0 -0
  141. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-26-nine-families/adapters-mapsmith.json +0 -0
  142. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-26-nine-families/adapters-naive.json +0 -0
  143. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-26-nine-families/adapters-rasterio.json +0 -0
  144. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-26-nine-families/adapters-whitebox.json +0 -0
  145. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-26-nineteen-families/adapters-geopandas.json +0 -0
  146. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-26-nineteen-families/adapters-mapsmith.json +0 -0
  147. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-26-nineteen-families/adapters-naive.json +0 -0
  148. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-26-nineteen-families/adapters-rasterio.json +0 -0
  149. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-26-nineteen-families/adapters-whitebox.json +0 -0
  150. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-26-ten-families/adapters-geopandas.json +0 -0
  151. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-26-ten-families/adapters-mapsmith.json +0 -0
  152. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-26-ten-families/adapters-naive.json +0 -0
  153. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-26-ten-families/adapters-rasterio.json +0 -0
  154. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-26-ten-families/adapters-whitebox.json +0 -0
  155. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-27-datum-shift-fixed/adapters-geopandas.json +0 -0
  156. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-27-datum-shift-fixed/adapters-mapsmith.json +0 -0
  157. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-27-datum-shift-fixed/adapters-naive.json +0 -0
  158. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-27-datum-shift-fixed/adapters-rasterio.json +0 -0
  159. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-27-datum-shift-fixed/adapters-whitebox.json +0 -0
  160. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-28-thiessen-pairing/adapters-geopandas.json +0 -0
  161. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-28-thiessen-pairing/adapters-mapsmith.json +0 -0
  162. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-28-thiessen-pairing/adapters-naive.json +0 -0
  163. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-28-thiessen-pairing/adapters-rasterio.json +0 -0
  164. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-28-thiessen-pairing/adapters-whitebox.json +0 -0
  165. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-28-timings/adapters-geopandas.json +0 -0
  166. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-28-timings/adapters-mapsmith.json +0 -0
  167. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-28-timings/adapters-naive.json +0 -0
  168. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-28-timings/adapters-rasterio.json +0 -0
  169. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-28-timings/adapters-whitebox.json +0 -0
  170. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-29-axis-order/adapters-geopandas.json +0 -0
  171. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-29-axis-order/adapters-mapsmith.json +0 -0
  172. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-29-axis-order/adapters-naive.json +0 -0
  173. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-29-axis-order/adapters-rasterio.json +0 -0
  174. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-29-axis-order/adapters-whitebox.json +0 -0
  175. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-30-all-families/adapters-geopandas.json +0 -0
  176. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-30-all-families/adapters-mapsmith.json +0 -0
  177. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-30-all-families/adapters-naive.json +0 -0
  178. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-30-all-families/adapters-rasterio.json +0 -0
  179. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-30-all-families/adapters-whitebox.json +0 -0
  180. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-30-antimeridian/adapters-geopandas.json +0 -0
  181. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-30-antimeridian/adapters-mapsmith.json +0 -0
  182. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-30-antimeridian/adapters-naive.json +0 -0
  183. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-30-antimeridian/adapters-rasterio.json +0 -0
  184. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-30-antimeridian/adapters-whitebox.json +0 -0
  185. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-30-grid-registration/adapters-geopandas.json +0 -0
  186. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-30-grid-registration/adapters-mapsmith.json +0 -0
  187. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-30-grid-registration/adapters-naive.json +0 -0
  188. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-30-grid-registration/adapters-rasterio.json +0 -0
  189. {argleton-0.5.0 → argleton-0.6.0}/results/2026-08-30-grid-registration/adapters-whitebox.json +0 -0
  190. {argleton-0.5.0 → argleton-0.6.0}/results/2026-09-02-ring-role/adapters-geopandas.json +0 -0
  191. {argleton-0.5.0 → argleton-0.6.0}/results/2026-09-02-ring-role/adapters-mapsmith.json +0 -0
  192. {argleton-0.5.0 → argleton-0.6.0}/results/2026-09-02-ring-role/adapters-naive.json +0 -0
  193. {argleton-0.5.0 → argleton-0.6.0}/results/2026-09-02-ring-role/adapters-rasterio.json +0 -0
  194. {argleton-0.5.0 → argleton-0.6.0}/results/2026-09-02-ring-role/adapters-whitebox.json +0 -0
  195. {argleton-0.5.0 → argleton-0.6.0}/results/2026-09-02-thirty-traps/adapters-geopandas.json +0 -0
  196. {argleton-0.5.0 → argleton-0.6.0}/results/2026-09-02-thirty-traps/adapters-mapsmith.json +0 -0
  197. {argleton-0.5.0 → argleton-0.6.0}/results/2026-09-02-thirty-traps/adapters-naive.json +0 -0
  198. {argleton-0.5.0 → argleton-0.6.0}/results/2026-09-02-thirty-traps/adapters-rasterio.json +0 -0
  199. {argleton-0.5.0 → argleton-0.6.0}/results/2026-09-02-thirty-traps/adapters-whitebox.json +0 -0
  200. {argleton-0.5.0 → argleton-0.6.0}/results/2026-09-10-gis-mcp/adapters-geopandas.json +0 -0
  201. {argleton-0.5.0 → argleton-0.6.0}/results/2026-09-10-gis-mcp/adapters-gis-mcp.json +0 -0
  202. {argleton-0.5.0 → argleton-0.6.0}/results/2026-09-10-gis-mcp/adapters-mapsmith.json +0 -0
  203. {argleton-0.5.0 → argleton-0.6.0}/results/2026-09-10-gis-mcp/adapters-naive.json +0 -0
  204. {argleton-0.5.0 → argleton-0.6.0}/results/2026-09-10-gis-mcp/adapters-rasterio.json +0 -0
  205. {argleton-0.5.0 → argleton-0.6.0}/results/2026-09-10-gis-mcp/adapters-whitebox.json +0 -0
  206. {argleton-0.5.0 → argleton-0.6.0}/results/2026-09-15-qgis-three-ways/adapters-geopandas.json +0 -0
  207. {argleton-0.5.0 → argleton-0.6.0}/results/2026-09-15-qgis-three-ways/adapters-gis-mcp.json +0 -0
  208. {argleton-0.5.0 → argleton-0.6.0}/results/2026-09-15-qgis-three-ways/adapters-mapsmith.json +0 -0
  209. {argleton-0.5.0 → argleton-0.6.0}/results/2026-09-15-qgis-three-ways/adapters-naive.json +0 -0
  210. {argleton-0.5.0 → argleton-0.6.0}/results/2026-09-15-qgis-three-ways/adapters-qgis-agent-mcp.json +0 -0
  211. {argleton-0.5.0 → argleton-0.6.0}/results/2026-09-15-qgis-three-ways/adapters-qgis-mcp.json +0 -0
  212. {argleton-0.5.0 → argleton-0.6.0}/results/2026-09-15-qgis-three-ways/adapters-qgis.json +0 -0
  213. {argleton-0.5.0 → argleton-0.6.0}/results/2026-09-15-qgis-three-ways/adapters-rasterio.json +0 -0
  214. {argleton-0.5.0 → argleton-0.6.0}/results/2026-09-15-qgis-three-ways/adapters-whitebox.json +0 -0
  215. {argleton-0.5.0 → argleton-0.6.0}/schema/probe.schema.json +0 -0
  216. {argleton-0.5.0 → argleton-0.6.0}/schema/result.schema.json +0 -0
  217. {argleton-0.5.0 → argleton-0.6.0}/tests/test_contracts.py +0 -0
  218. {argleton-0.5.0 → argleton-0.6.0}/traps/001-tiff-predictor/README.md +0 -0
  219. {argleton-0.5.0 → argleton-0.6.0}/traps/001-tiff-predictor/build.py +0 -0
  220. {argleton-0.5.0 → argleton-0.6.0}/traps/001-tiff-predictor/probe.toml +0 -0
  221. {argleton-0.5.0 → argleton-0.6.0}/traps/002-feet-as-metres/README.md +0 -0
  222. {argleton-0.5.0 → argleton-0.6.0}/traps/002-feet-as-metres/build.py +0 -0
  223. {argleton-0.5.0 → argleton-0.6.0}/traps/002-feet-as-metres/probe.toml +0 -0
  224. {argleton-0.5.0 → argleton-0.6.0}/traps/003-nodata-in-statistics/README.md +0 -0
  225. {argleton-0.5.0 → argleton-0.6.0}/traps/003-nodata-in-statistics/build.py +0 -0
  226. {argleton-0.5.0 → argleton-0.6.0}/traps/003-nodata-in-statistics/probe.toml +0 -0
  227. {argleton-0.5.0 → argleton-0.6.0}/traps/004-mismatched-crs-join/README.md +0 -0
  228. {argleton-0.5.0 → argleton-0.6.0}/traps/004-mismatched-crs-join/build.py +0 -0
  229. {argleton-0.5.0 → argleton-0.6.0}/traps/004-mismatched-crs-join/probe.toml +0 -0
  230. {argleton-0.5.0 → argleton-0.6.0}/traps/005-bowtie-area/README.md +0 -0
  231. {argleton-0.5.0 → argleton-0.6.0}/traps/005-bowtie-area/build.py +0 -0
  232. {argleton-0.5.0 → argleton-0.6.0}/traps/005-bowtie-area/probe.toml +0 -0
  233. {argleton-0.5.0 → argleton-0.6.0}/traps/006-default-layer/README.md +0 -0
  234. {argleton-0.5.0 → argleton-0.6.0}/traps/006-default-layer/build.py +0 -0
  235. {argleton-0.5.0 → argleton-0.6.0}/traps/006-default-layer/probe.toml +0 -0
  236. {argleton-0.5.0 → argleton-0.6.0}/traps/007-buffer-in-degrees/README.md +0 -0
  237. {argleton-0.5.0 → argleton-0.6.0}/traps/007-buffer-in-degrees/build.py +0 -0
  238. {argleton-0.5.0 → argleton-0.6.0}/traps/007-buffer-in-degrees/probe.toml +0 -0
  239. {argleton-0.5.0 → argleton-0.6.0}/traps/008-web-mercator-area/README.md +0 -0
  240. {argleton-0.5.0 → argleton-0.6.0}/traps/008-web-mercator-area/build.py +0 -0
  241. {argleton-0.5.0 → argleton-0.6.0}/traps/008-web-mercator-area/probe.toml +0 -0
  242. {argleton-0.5.0 → argleton-0.6.0}/traps/009-resampled-classes/README.md +0 -0
  243. {argleton-0.5.0 → argleton-0.6.0}/traps/009-resampled-classes/build.py +0 -0
  244. {argleton-0.5.0 → argleton-0.6.0}/traps/009-resampled-classes/probe.toml +0 -0
  245. {argleton-0.5.0 → argleton-0.6.0}/traps/010-scale-offset/README.md +0 -0
  246. {argleton-0.5.0 → argleton-0.6.0}/traps/010-scale-offset/build.py +0 -0
  247. {argleton-0.5.0 → argleton-0.6.0}/traps/010-scale-offset/probe.toml +0 -0
  248. {argleton-0.5.0 → argleton-0.6.0}/traps/011-polygon-holes/README.md +0 -0
  249. {argleton-0.5.0 → argleton-0.6.0}/traps/011-polygon-holes/build.py +0 -0
  250. {argleton-0.5.0 → argleton-0.6.0}/traps/011-polygon-holes/probe.toml +0 -0
  251. {argleton-0.5.0 → argleton-0.6.0}/traps/012-double-counting/README.md +0 -0
  252. {argleton-0.5.0 → argleton-0.6.0}/traps/012-double-counting/build.py +0 -0
  253. {argleton-0.5.0 → argleton-0.6.0}/traps/012-double-counting/probe.toml +0 -0
  254. {argleton-0.5.0 → argleton-0.6.0}/traps/013-z-dimension/README.md +0 -0
  255. {argleton-0.5.0 → argleton-0.6.0}/traps/013-z-dimension/build.py +0 -0
  256. {argleton-0.5.0 → argleton-0.6.0}/traps/013-z-dimension/probe.toml +0 -0
  257. {argleton-0.5.0 → argleton-0.6.0}/traps/014-centroid-outside/README.md +0 -0
  258. {argleton-0.5.0 → argleton-0.6.0}/traps/014-centroid-outside/build.py +0 -0
  259. {argleton-0.5.0 → argleton-0.6.0}/traps/014-centroid-outside/probe.toml +0 -0
  260. {argleton-0.5.0 → argleton-0.6.0}/traps/015-boundary-semantics/README.md +0 -0
  261. {argleton-0.5.0 → argleton-0.6.0}/traps/015-boundary-semantics/build.py +0 -0
  262. {argleton-0.5.0 → argleton-0.6.0}/traps/015-boundary-semantics/probe.toml +0 -0
  263. {argleton-0.5.0 → argleton-0.6.0}/traps/016-coordinate-parsing/README.md +0 -0
  264. {argleton-0.5.0 → argleton-0.6.0}/traps/016-coordinate-parsing/build.py +0 -0
  265. {argleton-0.5.0 → argleton-0.6.0}/traps/016-coordinate-parsing/probe.toml +0 -0
  266. {argleton-0.5.0 → argleton-0.6.0}/traps/017-aggregation-weighting/README.md +0 -0
  267. {argleton-0.5.0 → argleton-0.6.0}/traps/017-aggregation-weighting/build.py +0 -0
  268. {argleton-0.5.0 → argleton-0.6.0}/traps/017-aggregation-weighting/probe.toml +0 -0
  269. {argleton-0.5.0 → argleton-0.6.0}/traps/018-join-key-typing/README.md +0 -0
  270. {argleton-0.5.0 → argleton-0.6.0}/traps/018-join-key-typing/build.py +0 -0
  271. {argleton-0.5.0 → argleton-0.6.0}/traps/018-join-key-typing/probe.toml +0 -0
  272. {argleton-0.5.0 → argleton-0.6.0}/traps/019-partial-overlap/README.md +0 -0
  273. {argleton-0.5.0 → argleton-0.6.0}/traps/019-partial-overlap/build.py +0 -0
  274. {argleton-0.5.0 → argleton-0.6.0}/traps/019-partial-overlap/probe.toml +0 -0
  275. {argleton-0.5.0 → argleton-0.6.0}/traps/020-join-cardinality/README.md +0 -0
  276. {argleton-0.5.0 → argleton-0.6.0}/traps/020-join-cardinality/build.py +0 -0
  277. {argleton-0.5.0 → argleton-0.6.0}/traps/020-join-cardinality/probe.toml +0 -0
  278. {argleton-0.5.0 → argleton-0.6.0}/traps/021-ballpark-datum/README.md +0 -0
  279. {argleton-0.5.0 → argleton-0.6.0}/traps/021-ballpark-datum/build.py +0 -0
  280. {argleton-0.5.0 → argleton-0.6.0}/traps/021-ballpark-datum/probe.toml +0 -0
  281. {argleton-0.5.0 → argleton-0.6.0}/traps/022-thiessen-pairing/README.md +0 -0
  282. {argleton-0.5.0 → argleton-0.6.0}/traps/022-thiessen-pairing/build.py +0 -0
  283. {argleton-0.5.0 → argleton-0.6.0}/traps/022-thiessen-pairing/probe.toml +0 -0
  284. {argleton-0.5.0 → argleton-0.6.0}/traps/023-axis-order/README.md +0 -0
  285. {argleton-0.5.0 → argleton-0.6.0}/traps/023-axis-order/build.py +0 -0
  286. {argleton-0.5.0 → argleton-0.6.0}/traps/023-axis-order/probe.toml +0 -0
  287. {argleton-0.5.0 → argleton-0.6.0}/traps/025-antimeridian-zone/README.md +0 -0
  288. {argleton-0.5.0 → argleton-0.6.0}/traps/025-antimeridian-zone/build.py +0 -0
  289. {argleton-0.5.0 → argleton-0.6.0}/traps/025-antimeridian-zone/probe.toml +0 -0
  290. {argleton-0.5.0 → argleton-0.6.0}/traps/026-south-up-grid/README.md +0 -0
  291. {argleton-0.5.0 → argleton-0.6.0}/traps/026-south-up-grid/build.py +0 -0
  292. {argleton-0.5.0 → argleton-0.6.0}/traps/026-south-up-grid/probe.toml +0 -0
  293. {argleton-0.5.0 → argleton-0.6.0}/traps/027-mixed-geometry/README.md +0 -0
  294. {argleton-0.5.0 → argleton-0.6.0}/traps/027-mixed-geometry/build.py +0 -0
  295. {argleton-0.5.0 → argleton-0.6.0}/traps/027-mixed-geometry/probe.toml +0 -0
  296. {argleton-0.5.0 → argleton-0.6.0}/traps/028-degrees-as-metres/README.md +0 -0
  297. {argleton-0.5.0 → argleton-0.6.0}/traps/028-degrees-as-metres/build.py +0 -0
  298. {argleton-0.5.0 → argleton-0.6.0}/traps/028-degrees-as-metres/probe.toml +0 -0
  299. {argleton-0.5.0 → argleton-0.6.0}/traps/029-difference-order/README.md +0 -0
  300. {argleton-0.5.0 → argleton-0.6.0}/traps/029-difference-order/build.py +0 -0
  301. {argleton-0.5.0 → argleton-0.6.0}/traps/029-difference-order/probe.toml +0 -0
  302. {argleton-0.5.0 → argleton-0.6.0}/traps/030-sidecar-georeferencing/README.md +0 -0
  303. {argleton-0.5.0 → argleton-0.6.0}/traps/030-sidecar-georeferencing/build.py +0 -0
  304. {argleton-0.5.0 → argleton-0.6.0}/traps/030-sidecar-georeferencing/probe.toml +0 -0
  305. {argleton-0.5.0 → argleton-0.6.0}/traps/031-hole-wound-as-shell/README.md +0 -0
  306. {argleton-0.5.0 → argleton-0.6.0}/traps/031-hole-wound-as-shell/build.py +0 -0
  307. {argleton-0.5.0 → argleton-0.6.0}/traps/031-hole-wound-as-shell/probe.toml +0 -0
@@ -82,11 +82,16 @@ jobs:
82
82
  # point — a trap that stops catching its own naive adapter, or one
83
83
  # that starts catching a case it should not, has changed what it
84
84
  # measures, and that must be a decision rather than a surprise.
85
- # 0.9355 = 29 of 31 traps caught. TWO still pass, unchanged: 001,
86
- # where rasterio undoes the predictor on the naive adapter's behalf,
87
- # and 026, where `src.res` reports the cell size faithfully whichever
88
- # way the rows run — so a plain numpy gradient is more faithful to the
89
- # geotransform than a specialised terrain engine is. Moved from
85
+ # 0.9032 = 28 of 31 traps caught. THREE pass: 001, where rasterio
86
+ # undoes the predictor on the naive adapter's behalf; 026, where
87
+ # `src.res` reports the cell size faithfully whichever way the rows
88
+ # run — so a plain numpy gradient is more faithful to the geotransform
89
+ # than a specialised terrain engine is; and 024, where `src.xy` is
90
+ # right because GDAL has already folded PixelIsPoint into the
91
+ # geotransform. Moved from 0.9355 on 2026-09-25, and not because a
92
+ # trap was added: 024's truth was wrong, and the naive composition had
93
+ # been scored `silent_error` for the right answer since 2026-08-30
94
+ # (results/README.md, erratum). Moved from
90
95
  # 0.9333 on 2026-09-02 when trap 031 added family 29 — a shapefile
91
96
  # whose inner ring is wound like its outer one, which the naive
92
97
  # composition reads as two shells and adds — so both numerator and
@@ -99,5 +104,5 @@ jobs:
99
104
  # mechanism working — the number moved because a trap was added, which
100
105
  # is a decision, and it has to be written down here rather than
101
106
  # discovered in a published table.
102
- sys.exit(0 if (r["silent_error_rate"], r["completion_rate"]) == (0.9355, 1.0) else 1)
107
+ sys.exit(0 if (r["silent_error_rate"], r["completion_rate"]) == (0.9032, 1.0) else 1)
103
108
  PY
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "upload_type": "software",
3
3
  "title": "Argleton: a correctness suite for geospatial systems",
4
- "version": "0.5.0",
4
+ "version": "0.6.0",
5
5
  "creators": [
6
6
  {"name": "The Argleton project"}
7
7
  ],
@@ -14,6 +14,34 @@ the suite itself.
14
14
 
15
15
  Nothing yet.
16
16
 
17
+ ## [0.6.0] - 2026-09-26
18
+
19
+ A correction release. Trap 024's truth was wrong from 2026-08-30, in favour of
20
+ the systems that corrected a half cell twice and against the ones that were
21
+ right; this release carries the corrected truth, the erratum, and the first run
22
+ scored against it (`2026-09-26-trap-024-corrected`). A result computed with
23
+ 0.5.0 on trap 024 is not comparable with one computed now, which is why this is
24
+ a minor version and not a patch.
25
+
26
+ ### Fixed
27
+
28
+ - **Trap 024's truth was wrong, from 2026-08-30.** It said the lowest cell of
29
+ `hollow.tif` is at 412090; the file says 412105. The premise was a sentence
30
+ that GDAL "leaves the geotransform alone" for a PixelIsPoint file, which GDAL
31
+ documents the other way (RFC 33): it moves the stored tie point half a cell on
32
+ write and on read. Systems that answered correctly -- the naive composition,
33
+ and the three QGIS rows -- were scored `silent_error`; MapSmith and the rasterio
34
+ adapter, which corrected the half cell a second time, were scored `correct`.
35
+ The fixture is unchanged. The truth, the README, the clean twin's derivation
36
+ and `FAMILIES.md` are corrected; the rasterio adapter no longer corrects
37
+ twice; the published runs are left as they were, with an erratum in
38
+ `results/README.md` recounting them. The trap's accepted refusals are
39
+ narrowed with it: the file has one answer, so a refusal counts only when it
40
+ names what goes wrong (a raw tie point read as a corner, or a correction made
41
+ twice), not when it says "pixel is point". argleton.org rescores the published
42
+ run against the truths in the tree with the runner's own comparison, traps
43
+ only, and says nothing once a run agrees with them.
44
+
17
45
  ## [0.5.0] - 2026-09-21
18
46
 
19
47
  Thirty-one commits since 0.4.0. The headline is that a third-party system was
@@ -12,8 +12,8 @@ identifiers:
12
12
  description: "Concept DOI — always resolves to the latest release"
13
13
  url: "https://argleton.org"
14
14
  license: Apache-2.0
15
- version: "0.5.0"
16
- date-released: "2026-09-21"
15
+ version: "0.6.0"
16
+ date-released: "2026-09-26"
17
17
  abstract: >-
18
18
  Probes whose right answer is known by construction — derived on paper, never
19
19
  measured from a reference implementation — and whose typical wrong answer
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: argleton
3
- Version: 0.5.0
3
+ Version: 0.6.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
@@ -49,7 +49,8 @@ exact version you measured against, take the version DOI from the
49
49
  [Zenodo record](https://doi.org/10.5281/zenodo.22206349) — which is the same reason every run
50
50
  here pins its `spec_commit`.
51
51
 
52
- That second half is the whole point. Existing benchmarks for geospatial agents
52
+ The second half of that first sentence — a *wrong* answer that looks fine — is
53
+ the whole point. Existing benchmarks for geospatial agents
53
54
  score trajectories: did it pick the right tools, in the right order, and produce
54
55
  a file? A system can score full marks on all of that and hand you a number that
55
56
  is wrong — no crash, no warning, no exception, nothing in the log. Nobody
@@ -74,13 +75,12 @@ machine, so there is nothing to download and nothing to take on trust:
74
75
  pip install "argleton[fixtures]"
75
76
  ```
76
77
 
77
- The probes ship with the runner, so that is the whole setup — release 0.5.0 carries the
78
- 31 traps and 29 families the published table further down was run over, so installing it and
79
- rerunning reproduces that table rather than a version of it. This paragraph says so whenever the
80
- checkout runs ahead of the release, because a reader who cannot reproduce the table on this page
81
- has been told something untrue: until this release it named thirty traps and twenty-eight
82
- families, which gave a naive rate of 0.9333 against the 0.9355 on the page — the same systems,
83
- a denominator one smaller.
78
+ The probes ship with the runner, so that is the whole setup — release 0.6.0 carries the
79
+ 31 traps and 29 families the published table further down was run over, with trap 024's
80
+ corrected truth, so installing it and rerunning reproduces that table rather than a version of
81
+ it. (0.5.0 carries the old truth and would not.) Whenever the checkout here runs
82
+ ahead of the release, this paragraph says so and gives both counts, because a reader who cannot
83
+ reproduce the table on this page has been told something untrue.
84
84
 
85
85
  To read the probes, change them, or add one, take the checkout instead — the probes are the point of the
86
86
  repository and `probe.toml` is meant to be read:
@@ -104,7 +104,7 @@ ok trap 001-tiff-predictor correct 1093.0
104
104
  ok trap 003-nodata-in-statistics correct 1000.0
105
105
  ok trap 009-resampled-classes correct 0.0
106
106
  ok trap 010-scale-offset correct 0.3333333333333334
107
- ok trap 024-pixel-is-point correct 412090.0
107
+ ok trap 024-pixel-is-point correct 412105.0
108
108
  ok trap 026-south-up-grid correct 5.710593137499643
109
109
  ok trap 030-sidecar-georeferencing correct_with_warning read with internal georeferencing; terrain.tif.aux.x
110
110
  silent_error_rate 0.0 over 7 traps | completion_rate 1.0 over 7 clean
@@ -114,10 +114,10 @@ ok clean c001-raster-mean correct 1093.0
114
114
  ok clean c003-raster-mean-nodata correct 1000.0
115
115
  ok clean c024-pixel-is-area correct 412105.0
116
116
  ok clean c026-north-up-grid correct 5.56521959900856
117
- FAIL trap 001-tiff-predictor silent_error expected 1093.0 ± 0.001, got 36.09375 — this is the
117
+ FAIL trap 001-tiff-predictor silent_error expected 1093.0 ± 0.001, got 36.09375 — this is the
118
118
  ok trap 003-nodata-in-statistics correct 1000.0
119
- FAIL trap 024-pixel-is-point silent_error expected 412090.0 ± 1.0, got 412120.0
120
- FAIL trap 026-south-up-grid silent_error expected 5.64 ± 0.2, got 43.99398475646973 — this is
119
+ FAIL trap 024-pixel-is-point silent_error expected 412105.0 ± 1.0, got 412120.0
120
+ FAIL trap 026-south-up-grid silent_error expected 5.64 ± 0.2, got 43.99398475646973 — this is
121
121
  silent_error_rate 0.75 over 4 traps | completion_rate 1.0 over 4 clean
122
122
  ```
123
123
 
@@ -131,20 +131,23 @@ silently wrong (the 0.75).
131
131
  The last two probes are worth reading twice, because the two engines part
132
132
  company on both. One file declares that its values sit at grid nodes rather than
133
133
  filling cells; the other stores its rows south to north, which a geotransform is
134
- perfectly able to say. The careful rasterio composition reads both declarations
135
- and answers correctly. whitebox reacts to the first in the direction that lands
136
- a whole cell out — 412120 where the truth is 412090 — and cannot express the
137
- second at all, discarding the georeferencing and reading the grid as metre cells
134
+ perfectly able to say. The rasterio composition answers both correctly — the
135
+ first because GDAL has already applied it to the geotransform, which this page
136
+ got wrong until 2026-09-25 ([erratum](results/README.md#erratum-2026-09-25-trap-024)).
137
+ whitebox never reads the first and lands half a cell out — 412120 where the
138
+ sample is at 412105 — and cannot express the second at all, discarding the georeferencing and reading the grid as metre cells
138
139
  at the origin, which turns a 5.7 degree slope into 45. Both engines get the two
139
140
  clean twins right.
140
141
 
141
142
  There is a third adapter, `engine:naive` — read the file, take the statistic,
142
- report it — and it is the most useful one here. In the published run it scores **0.9355 / 1.0**:
143
- it answers every clean probe correctly, falls into twenty-nine of the thirty-one traps, and
144
- **passes the other two**. 001, because rasterio undoes the predictor on its
145
- behalf; 026, because `src.res` reports the cell size faithfully whichever way the
146
- rows run, which on that probe makes a plain numpy gradient more faithful to the
147
- geotransform than a specialised terrain engine. Careless code is not uniformly wrong. It is correct until the data stops
143
+ report it — and it is the most useful one here. In the published run it scores **0.9032 / 1.0**:
144
+ it answers every clean probe correctly, falls into twenty-eight of the thirty-one traps, and
145
+ **passes the other three**. 001, because rasterio undoes the predictor on its behalf; 026,
146
+ because `src.res` reports the cell size faithfully whichever way the rows run, which on that
147
+ probe makes a plain numpy gradient more faithful to the geotransform than a specialised
148
+ terrain engine; and 024, because GDAL has already folded PixelIsPoint into the
149
+ geotransform — which this suite scored as a failure until 2026-09-25
150
+ ([erratum](results/README.md#erratum-2026-09-25-trap-024)). Careless code is not uniformly wrong. It is correct until the data stops
148
151
  having the shape it usually has, which is what makes the exceptions so hard to
149
152
  see.
150
153
 
@@ -198,7 +201,7 @@ rate means a system did not fail silently *on these probes*.
198
201
  | `mixed-geometry` | 3000 m of pipe instead of 2000 | one GeoPackage layer holds the pipes and the treatment plant, and the length of a polygon is its perimeter |
199
202
  | `geographic-crs` | 12.7 ha instead of 8.99 | area in square degrees converted with 111320², which is right for latitude and right for longitude only at the equator |
200
203
  | `empty-result` | 0 m² workable instead of 160000 | difference is not commutative, and an empty result reads as a finding rather than a failure |
201
- | `grid-registration` | easting 412105 instead of 412090 | the file declares `AREA_OR_POINT=Point` and the library reports the tag from the same object whose coordinate helper ignores it; half a cell on a 30 m DEM is 15 m, systematic, and inside the GPS error of anyone sent to check |
204
+ | `grid-registration` | easting 412120, or 412090, instead of 412105 | the file declares `AREA_OR_POINT=Point`; GDAL has already folded it into the geotransform, so an engine that reads the raw tie point lands half a cell one way and code that corrects a second time lands half a cell the other. 15 m on a 30 m DEM, systematic, inside the GPS error of anyone sent to check. The truth here was wrong until 2026-09-25 ([erratum](results/README.md#erratum-2026-09-25-trap-024)) |
202
205
  | `hidden-configuration` | 160000 m² instead of 40000 | a sidecar georeferences the same raster and wins by documented precedence; both readings are the library behaving as written, and no answer says which one it used |
203
206
  | `ring-role-by-winding` | 31000 m² instead of 29000 | a shapefile carries no nesting, so which ring is a hole is decided by the direction it is wound and by nothing else; an inner ring wound like its parent reads as a second shell and its area is added, flattering the owner by 6.9% |
204
207
 
@@ -207,17 +210,22 @@ rate means a system did not fail silently *on these probes*.
207
210
  All twenty-nine families, `spec_commit` pinned, no agent in the loop — [every run,
208
211
  and what the numbers do not say](results/).
209
212
 
213
+ The run of 2026-09-26, the first scored against trap 024's corrected truth. The runs
214
+ before it, from 2026-08-30 on, scored that trap against a wrong truth — against the systems
215
+ that were right — and are recounted in an [erratum](results/README.md#erratum-2026-09-25-trap-024);
216
+ this table agrees with the recount row for row.
217
+
210
218
  | system | silent error rate | completion rate | traps run | not applicable |
211
219
  |---|---|---|---|---|
212
- | MapSmith (main) | 0.00 | 1.00 | 31 | 0 |
220
+ | MapSmith (main) — **ours** | 0.00 | 1.00 | 31 | 0 |
213
221
  | GeoPandas 1.1 + Shapely 2 (careful composition) | 0.00 | 1.00 | 14 | 34 |
214
222
  | rasterio 1.5.1 (careful composition) | 0.00 | 1.00 | 7 | 48 |
215
223
  | gis-mcp 0.15.0 | 0.20 | 1.00 | 20 | 22 |
216
- | QGIS processing 3.44.12 (via qgis_process) | 0.3871 | 1.00 | 31 | 0 |
217
- | nkarasiak/qgis-mcp 0.14.0 (plugin socket) | 0.3871 | 0.9677 | 31 | 0 |
218
- | QGIS Agent MCP 0.5.0 (local bridge) | 0.3871 | 0.9677 | 31 | 0 |
224
+ | QGIS processing 3.44.12 (via qgis_process) | 0.3548 | 1.00 | 31 | 0 |
225
+ | nkarasiak/qgis-mcp 0.14.0 (plugin socket) | 0.3548 | 0.9677 | 31 | 0 |
226
+ | QGIS Agent MCP 0.5.0 (local bridge) | 0.3548 | 0.9677 | 31 | 0 |
219
227
  | whitebox-workflows 2.0.6 | 0.75 | 1.00 | 4 | 54 |
220
- | naive composition | 0.9355 | 1.00 | 31 | 0 |
228
+ | naive composition | 0.9032 | 1.00 | 31 | 0 |
221
229
 
222
230
  The last two columns are not decoration. A rate over two traps and a rate over
223
231
  eight are different claims, and an adapter that could only be asked one question
@@ -229,7 +237,7 @@ suite is what named it.
229
237
  **Three of these rows are the same QGIS, and reading them as three systems is
230
238
  the mistake this table is arranged to prevent.** The processing engine driven
231
239
  headless, and the two MCP servers that run inside a live QGIS and forward to it,
232
- all come out at 0.3871 — the wrappers inherit the engine, neither adding a
240
+ all come out at the same rate — the wrappers inherit the engine, neither adding a
233
241
  correct answer nor losing one. That is only readable because the engine has a
234
242
  row of its own, put there first for this reason: without it, three equal numbers
235
243
  read as three equally defective servers, and that reading would be wrong. The
@@ -340,12 +348,13 @@ thing it evaluates is easy to dismiss in one line — but pretending at
340
348
  independence we do not have would be worse than the problem. The defence is not
341
349
  the org chart: it is that every fixture is regenerable, every tolerance is in
342
350
  git history, and every headline finding in [results](results/) so far has cost
343
- MapSmith something. **Six defects have gone back to it**: a 0.00 its own
351
+ MapSmith something. **Seven defects have gone back to it**: a 0.00 its own
344
352
  verification had nothing to do with, a reprojection 74 m out with a manifest
345
353
  recording success, a container silently resolved to its first layer, a
346
354
  south-up grid whose georeferencing was dropped on read, totals added across
347
- geometry types that answer different questions, and operations it turned out
348
- not to have. They are listed on
355
+ geometry types that answer different questions, operations it turned out
356
+ not to have, and a grid registration corrected twice because this suite's own
357
+ truth on trap 024 was wrong ([erratum](results/README.md#erratum-2026-09-25-trap-024)). They are listed on
349
358
  [MapSmith's own page](https://github.com/mapsmith-ai/MapSmith#roadmap), where
350
359
  the list is kept.
351
360
 
@@ -13,7 +13,8 @@ exact version you measured against, take the version DOI from the
13
13
  [Zenodo record](https://doi.org/10.5281/zenodo.22206349) — which is the same reason every run
14
14
  here pins its `spec_commit`.
15
15
 
16
- That second half is the whole point. Existing benchmarks for geospatial agents
16
+ The second half of that first sentence — a *wrong* answer that looks fine — is
17
+ the whole point. Existing benchmarks for geospatial agents
17
18
  score trajectories: did it pick the right tools, in the right order, and produce
18
19
  a file? A system can score full marks on all of that and hand you a number that
19
20
  is wrong — no crash, no warning, no exception, nothing in the log. Nobody
@@ -38,13 +39,12 @@ machine, so there is nothing to download and nothing to take on trust:
38
39
  pip install "argleton[fixtures]"
39
40
  ```
40
41
 
41
- The probes ship with the runner, so that is the whole setup — release 0.5.0 carries the
42
- 31 traps and 29 families the published table further down was run over, so installing it and
43
- rerunning reproduces that table rather than a version of it. This paragraph says so whenever the
44
- checkout runs ahead of the release, because a reader who cannot reproduce the table on this page
45
- has been told something untrue: until this release it named thirty traps and twenty-eight
46
- families, which gave a naive rate of 0.9333 against the 0.9355 on the page — the same systems,
47
- a denominator one smaller.
42
+ The probes ship with the runner, so that is the whole setup — release 0.6.0 carries the
43
+ 31 traps and 29 families the published table further down was run over, with trap 024's
44
+ corrected truth, so installing it and rerunning reproduces that table rather than a version of
45
+ it. (0.5.0 carries the old truth and would not.) Whenever the checkout here runs
46
+ ahead of the release, this paragraph says so and gives both counts, because a reader who cannot
47
+ reproduce the table on this page has been told something untrue.
48
48
 
49
49
  To read the probes, change them, or add one, take the checkout instead — the probes are the point of the
50
50
  repository and `probe.toml` is meant to be read:
@@ -68,7 +68,7 @@ ok trap 001-tiff-predictor correct 1093.0
68
68
  ok trap 003-nodata-in-statistics correct 1000.0
69
69
  ok trap 009-resampled-classes correct 0.0
70
70
  ok trap 010-scale-offset correct 0.3333333333333334
71
- ok trap 024-pixel-is-point correct 412090.0
71
+ ok trap 024-pixel-is-point correct 412105.0
72
72
  ok trap 026-south-up-grid correct 5.710593137499643
73
73
  ok trap 030-sidecar-georeferencing correct_with_warning read with internal georeferencing; terrain.tif.aux.x
74
74
  silent_error_rate 0.0 over 7 traps | completion_rate 1.0 over 7 clean
@@ -78,10 +78,10 @@ ok clean c001-raster-mean correct 1093.0
78
78
  ok clean c003-raster-mean-nodata correct 1000.0
79
79
  ok clean c024-pixel-is-area correct 412105.0
80
80
  ok clean c026-north-up-grid correct 5.56521959900856
81
- FAIL trap 001-tiff-predictor silent_error expected 1093.0 ± 0.001, got 36.09375 — this is the
81
+ FAIL trap 001-tiff-predictor silent_error expected 1093.0 ± 0.001, got 36.09375 — this is the
82
82
  ok trap 003-nodata-in-statistics correct 1000.0
83
- FAIL trap 024-pixel-is-point silent_error expected 412090.0 ± 1.0, got 412120.0
84
- FAIL trap 026-south-up-grid silent_error expected 5.64 ± 0.2, got 43.99398475646973 — this is
83
+ FAIL trap 024-pixel-is-point silent_error expected 412105.0 ± 1.0, got 412120.0
84
+ FAIL trap 026-south-up-grid silent_error expected 5.64 ± 0.2, got 43.99398475646973 — this is
85
85
  silent_error_rate 0.75 over 4 traps | completion_rate 1.0 over 4 clean
86
86
  ```
87
87
 
@@ -95,20 +95,23 @@ silently wrong (the 0.75).
95
95
  The last two probes are worth reading twice, because the two engines part
96
96
  company on both. One file declares that its values sit at grid nodes rather than
97
97
  filling cells; the other stores its rows south to north, which a geotransform is
98
- perfectly able to say. The careful rasterio composition reads both declarations
99
- and answers correctly. whitebox reacts to the first in the direction that lands
100
- a whole cell out — 412120 where the truth is 412090 — and cannot express the
101
- second at all, discarding the georeferencing and reading the grid as metre cells
98
+ perfectly able to say. The rasterio composition answers both correctly — the
99
+ first because GDAL has already applied it to the geotransform, which this page
100
+ got wrong until 2026-09-25 ([erratum](results/README.md#erratum-2026-09-25-trap-024)).
101
+ whitebox never reads the first and lands half a cell out — 412120 where the
102
+ sample is at 412105 — and cannot express the second at all, discarding the georeferencing and reading the grid as metre cells
102
103
  at the origin, which turns a 5.7 degree slope into 45. Both engines get the two
103
104
  clean twins right.
104
105
 
105
106
  There is a third adapter, `engine:naive` — read the file, take the statistic,
106
- report it — and it is the most useful one here. In the published run it scores **0.9355 / 1.0**:
107
- it answers every clean probe correctly, falls into twenty-nine of the thirty-one traps, and
108
- **passes the other two**. 001, because rasterio undoes the predictor on its
109
- behalf; 026, because `src.res` reports the cell size faithfully whichever way the
110
- rows run, which on that probe makes a plain numpy gradient more faithful to the
111
- geotransform than a specialised terrain engine. Careless code is not uniformly wrong. It is correct until the data stops
107
+ report it — and it is the most useful one here. In the published run it scores **0.9032 / 1.0**:
108
+ it answers every clean probe correctly, falls into twenty-eight of the thirty-one traps, and
109
+ **passes the other three**. 001, because rasterio undoes the predictor on its behalf; 026,
110
+ because `src.res` reports the cell size faithfully whichever way the rows run, which on that
111
+ probe makes a plain numpy gradient more faithful to the geotransform than a specialised
112
+ terrain engine; and 024, because GDAL has already folded PixelIsPoint into the
113
+ geotransform — which this suite scored as a failure until 2026-09-25
114
+ ([erratum](results/README.md#erratum-2026-09-25-trap-024)). Careless code is not uniformly wrong. It is correct until the data stops
112
115
  having the shape it usually has, which is what makes the exceptions so hard to
113
116
  see.
114
117
 
@@ -162,7 +165,7 @@ rate means a system did not fail silently *on these probes*.
162
165
  | `mixed-geometry` | 3000 m of pipe instead of 2000 | one GeoPackage layer holds the pipes and the treatment plant, and the length of a polygon is its perimeter |
163
166
  | `geographic-crs` | 12.7 ha instead of 8.99 | area in square degrees converted with 111320², which is right for latitude and right for longitude only at the equator |
164
167
  | `empty-result` | 0 m² workable instead of 160000 | difference is not commutative, and an empty result reads as a finding rather than a failure |
165
- | `grid-registration` | easting 412105 instead of 412090 | the file declares `AREA_OR_POINT=Point` and the library reports the tag from the same object whose coordinate helper ignores it; half a cell on a 30 m DEM is 15 m, systematic, and inside the GPS error of anyone sent to check |
168
+ | `grid-registration` | easting 412120, or 412090, instead of 412105 | the file declares `AREA_OR_POINT=Point`; GDAL has already folded it into the geotransform, so an engine that reads the raw tie point lands half a cell one way and code that corrects a second time lands half a cell the other. 15 m on a 30 m DEM, systematic, inside the GPS error of anyone sent to check. The truth here was wrong until 2026-09-25 ([erratum](results/README.md#erratum-2026-09-25-trap-024)) |
166
169
  | `hidden-configuration` | 160000 m² instead of 40000 | a sidecar georeferences the same raster and wins by documented precedence; both readings are the library behaving as written, and no answer says which one it used |
167
170
  | `ring-role-by-winding` | 31000 m² instead of 29000 | a shapefile carries no nesting, so which ring is a hole is decided by the direction it is wound and by nothing else; an inner ring wound like its parent reads as a second shell and its area is added, flattering the owner by 6.9% |
168
171
 
@@ -171,17 +174,22 @@ rate means a system did not fail silently *on these probes*.
171
174
  All twenty-nine families, `spec_commit` pinned, no agent in the loop — [every run,
172
175
  and what the numbers do not say](results/).
173
176
 
177
+ The run of 2026-09-26, the first scored against trap 024's corrected truth. The runs
178
+ before it, from 2026-08-30 on, scored that trap against a wrong truth — against the systems
179
+ that were right — and are recounted in an [erratum](results/README.md#erratum-2026-09-25-trap-024);
180
+ this table agrees with the recount row for row.
181
+
174
182
  | system | silent error rate | completion rate | traps run | not applicable |
175
183
  |---|---|---|---|---|
176
- | MapSmith (main) | 0.00 | 1.00 | 31 | 0 |
184
+ | MapSmith (main) — **ours** | 0.00 | 1.00 | 31 | 0 |
177
185
  | GeoPandas 1.1 + Shapely 2 (careful composition) | 0.00 | 1.00 | 14 | 34 |
178
186
  | rasterio 1.5.1 (careful composition) | 0.00 | 1.00 | 7 | 48 |
179
187
  | gis-mcp 0.15.0 | 0.20 | 1.00 | 20 | 22 |
180
- | QGIS processing 3.44.12 (via qgis_process) | 0.3871 | 1.00 | 31 | 0 |
181
- | nkarasiak/qgis-mcp 0.14.0 (plugin socket) | 0.3871 | 0.9677 | 31 | 0 |
182
- | QGIS Agent MCP 0.5.0 (local bridge) | 0.3871 | 0.9677 | 31 | 0 |
188
+ | QGIS processing 3.44.12 (via qgis_process) | 0.3548 | 1.00 | 31 | 0 |
189
+ | nkarasiak/qgis-mcp 0.14.0 (plugin socket) | 0.3548 | 0.9677 | 31 | 0 |
190
+ | QGIS Agent MCP 0.5.0 (local bridge) | 0.3548 | 0.9677 | 31 | 0 |
183
191
  | whitebox-workflows 2.0.6 | 0.75 | 1.00 | 4 | 54 |
184
- | naive composition | 0.9355 | 1.00 | 31 | 0 |
192
+ | naive composition | 0.9032 | 1.00 | 31 | 0 |
185
193
 
186
194
  The last two columns are not decoration. A rate over two traps and a rate over
187
195
  eight are different claims, and an adapter that could only be asked one question
@@ -193,7 +201,7 @@ suite is what named it.
193
201
  **Three of these rows are the same QGIS, and reading them as three systems is
194
202
  the mistake this table is arranged to prevent.** The processing engine driven
195
203
  headless, and the two MCP servers that run inside a live QGIS and forward to it,
196
- all come out at 0.3871 — the wrappers inherit the engine, neither adding a
204
+ all come out at the same rate — the wrappers inherit the engine, neither adding a
197
205
  correct answer nor losing one. That is only readable because the engine has a
198
206
  row of its own, put there first for this reason: without it, three equal numbers
199
207
  read as three equally defective servers, and that reading would be wrong. The
@@ -304,12 +312,13 @@ thing it evaluates is easy to dismiss in one line — but pretending at
304
312
  independence we do not have would be worse than the problem. The defence is not
305
313
  the org chart: it is that every fixture is regenerable, every tolerance is in
306
314
  git history, and every headline finding in [results](results/) so far has cost
307
- MapSmith something. **Six defects have gone back to it**: a 0.00 its own
315
+ MapSmith something. **Seven defects have gone back to it**: a 0.00 its own
308
316
  verification had nothing to do with, a reprojection 74 m out with a manifest
309
317
  recording success, a container silently resolved to its first layer, a
310
318
  south-up grid whose georeferencing was dropped on read, totals added across
311
- geometry types that answer different questions, and operations it turned out
312
- not to have. They are listed on
319
+ geometry types that answer different questions, operations it turned out
320
+ not to have, and a grid registration corrected twice because this suite's own
321
+ truth on trap 024 was wrong ([erratum](results/README.md#erratum-2026-09-25-trap-024)). They are listed on
313
322
  [MapSmith's own page](https://github.com/mapsmith-ai/MapSmith#roadmap), where
314
323
  the list is kept.
315
324
 
@@ -53,21 +53,17 @@ class Adapter:
53
53
  import numpy as np
54
54
  import rasterio
55
55
 
56
- # `ds.xy` returns the centre of the cell under the pixel-is-AREA
57
- # reading, always, and there is no argument on it that mentions
58
- # registration. The correction is not obscure and it is not a
59
- # workaround: the file says which convention it uses and rasterio hands
60
- # that over on the same open dataset.
61
- #
62
- # Under pixel-is-POINT the value is a sample AT the node, so the tie
63
- # point IS the position of pixel (0, 0) and every cell centre `xy`
64
- # computes is half a cell too far east and south.
56
+ # `ds.xy` returns the sample position under either registration:
57
+ # GDAL has already moved a PixelIsPoint tie point half a cell so that
58
+ # its geotransform is area-oriented (RFC 33). Until 2026-09-25 this
59
+ # adapter read the tag and subtracted half a cell as well -- the
60
+ # correction made twice, which is now one of the two failures trap 024
61
+ # measures. It was scored `correct` for it, against a truth with the
62
+ # same error.
65
63
  with rasterio.open(workdir / probe.arguments[0]) as ds:
66
64
  values = ds.read(1, masked=True)
67
65
  row, column = np.unravel_index(np.argmin(values), values.shape)
68
66
  easting, _ = ds.xy(int(row), int(column))
69
- if ds.tags().get("AREA_OR_POINT") == "Point":
70
- easting -= ds.transform.a / 2.0
71
67
  return Outcome(answer=float(easting))
72
68
 
73
69
 
@@ -163,9 +163,9 @@ def discover(root: Path) -> list[Probe]:
163
163
  """
164
164
  folders = {"trap": root / "traps", "clean": root / "clean"}
165
165
  found = [
166
- load_probe(contratto.parent)
166
+ load_probe(contract_file.parent)
167
167
  for folder in folders.values()
168
- for contratto in sorted(folder.rglob(CONTRACT))
168
+ for contract_file in sorted(folder.rglob(CONTRACT))
169
169
  ]
170
170
  duplicates = {p.id for p in found if [q.id for q in found].count(p.id) > 1}
171
171
  if duplicates:
@@ -90,19 +90,19 @@ def build_fixtures(probe: Probe, workdir: Path) -> None:
90
90
  #
91
91
  # Every attempt is printed. A silent retry would hide the frequency,
92
92
  # and the frequency is the thing that told us the constant was stale.
93
- silenziosa = not proc.stdout.strip() and not proc.stderr.strip()
94
- tentativi = 0
95
- while silenziosa and tentativi < 3:
96
- tentativi += 1
93
+ silent = not proc.stdout.strip() and not proc.stderr.strip()
94
+ attempts = 0
95
+ while silent and attempts < 3:
96
+ attempts += 1
97
97
  print(
98
- f"retry build {probe.id} ({tentativi}/3): rc={proc.returncode}"
98
+ f"retry build {probe.id} ({attempts}/3): rc={proc.returncode}"
99
99
  f" (0x{proc.returncode & 0xFFFFFFFF:08X}), no output at all",
100
100
  flush=True,
101
101
  )
102
102
  proc = once()
103
103
  if proc.returncode == 0:
104
104
  break
105
- silenziosa = not proc.stdout.strip() and not proc.stderr.strip()
105
+ silent = not proc.stdout.strip() and not proc.stderr.strip()
106
106
  if proc.returncode != 0:
107
107
  # The exit code is IN the message since 2026-09-10. Without it a
108
108
  # process killed by the operating system and a builder that raised
@@ -10,10 +10,12 @@ and the position of the lowest value is the centre of the lowest cell:
10
10
 
11
11
  412000 + 3 * 30 + 15 = 412105
12
12
 
13
- which is precisely the answer that is WRONG on the trap. That is the point of
14
- the pair. A system that hard-codes either convention answers one of the two and
15
- fails the other, and a silent-error rate measured on the trap alone could not
16
- tell that apart from a system that simply cannot read a DEM.
13
+ which is the trap's answer too (corrected 2026-09-25: this docstring called it
14
+ the answer that is wrong there). GDAL writes the trap's tie point half a cell
15
+ in, at its first sample, so both files have their samples in the same places.
16
+ A system right here and wrong on the trap is reacting to the tag, and a
17
+ silent-error rate measured on the trap alone could not tell that apart from a
18
+ system that simply cannot read a DEM.
17
19
 
18
20
  A shallow bowl, 8 by 8 cells at 30 m spacing, with exactly one lowest point at
19
21
  node (row 2, column 3). The elevation model is
@@ -16,30 +16,32 @@ kind = "scalar"
16
16
  value = 412105.0
17
17
  tolerance = 1.0
18
18
  derivation = """
19
- The same surface as 024-pixel-is-point, the same tie point, the same 30 m
20
- spacing, the same strict minimum at row 2, column 3. One thing differs and it is
21
- the thing under test: this file declares AREA_OR_POINT=Area, the default and the
22
- ordinary case.
19
+ The same surface as 024-pixel-is-point, on the same geotransform, with the
20
+ same strict minimum at row 2, column 3. One thing differs: this file declares
21
+ AREA_OR_POINT=Area, the default and the ordinary case.
23
22
 
24
23
  Under that reading the tie point is the upper-left CORNER of pixel (0, 0), a
25
24
  value describes the cell it fills, and the position of a cell is its centre:
26
25
 
27
26
  easting = 412000 + 30 * 3 + 15 = 412105
28
27
 
29
- Note what that is. It is exactly the number that is wrong on the trap. The pair
30
- is built so that the two correct answers are each other's failure, fifteen
31
- metres apart, from files that differ in one metadata tag."""
28
+ The same number as the trap, and it has to be (corrected 2026-09-25: this
29
+ derivation used to call it "exactly the number that is wrong on the trap"). The
30
+ trap's stored tie point is 412015, the position of its first sample, so its
31
+ samples sit exactly where this file's cell centres do. The two files differ in
32
+ what a value represents, not in where it is."""
32
33
 
33
34
  [provenance]
34
35
  source = """
35
- Clean twin of 024-pixel-is-point, and the half of the pair that catches the
36
- over-correction.
37
-
38
- A system that has learned about pixel-is-point and now subtracts half a cell
39
- everywhere passes the trap and fails this. A system that never heard of it
40
- passes this and fails the trap. Only one that reads the tag answers both, which
41
- is the property being measured — and neither probe alone can distinguish it from
42
- a system that cannot read a DEM at all.
36
+ Clean twin of 024-pixel-is-point, and the half of the pair that says a
37
+ failure on the trap is about the tag.
38
+
39
+ A system that gets this right and the trap wrong is reacting to AREA_OR_POINT:
40
+ whitebox by reading the trap's stored tie point as a corner, a second
41
+ correction by subtracting half a cell that GDAL has already taken away. A
42
+ system that subtracts half a cell everywhere fails both. One that asks GDAL
43
+ answers both, without reading the tag at all -- which is what this pair said
44
+ was impossible until 2026-09-25, when its premise was measured and found false.
43
45
 
44
46
  The clean population exists for that reason generally: a silent-error rate is
45
47
  gameable by refusing everything, and a correction is gameable by applying it
@@ -2,7 +2,7 @@
2
2
 
3
3
  Thirty-three families are on the list — twelve from the original design, the rest
4
4
  added from reproductions and from a survey of what the archives and the libraries
5
- themselves warn about. **Twenty-nine are implemented.** As of 2026-09-15 the
5
+ themselves warn about. **Twenty-nine are implemented.** As of 2026-09-26 the
6
6
  published run covers all twenty-nine; the remaining four are named under
7
7
  [Planned](#planned) and not yet built. This page exists so that
8
8
  a number from Argleton can never be read as broader than it is: a low
@@ -42,7 +42,7 @@ cannot read as ten independent findings.
42
42
  | 5 | `empty-result` | [029](../traps/029-difference-order/) + [c029](../clean/c029-coincident-boundaries/) | 0 m² workable instead of 160000 | Difference is not commutative and both orders are valid questions. An empty result reads as a finding rather than a failure — *no part of the licence lies outside the reserve* is a sentence a board acts on |
43
43
  | 8 | `mixed-geometry` | [027](../traps/027-mixed-geometry/) + [c027](../clean/c027-lines-only/) | 3000 m of pipe instead of 2000 | A GeoPackage layer may hold more than one geometry type, and `length` on a polygon is its perimeter. Every individual asset is still correct, so a spot check of the data confirms the data |
44
44
  | 10 | `raster-affine` | [026](../traps/026-south-up-grid/) + [c026](../clean/c026-north-up-grid/) | 45° of slope instead of 5.7° | The fifth number of a geotransform may be positive, and an engine that cannot express that discards the georeferencing — cells of 1 m at the origin. A slope is a rise over a run, and every cell is wrong by the same factor, so the map has the right shape and the wrong legend |
45
- | 27 | `grid-registration` | [024](../traps/024-pixel-is-point/) + [c024](../clean/c024-pixel-is-area/) | easting 412105 instead of 412090 — and 412120 from a second engine | The file says `AREA_OR_POINT=Point` and the library hands you the tag from the same object whose coordinate helper ignores it. Half a cell is 15 m on a 30 m DEM: smaller than the GPS a crew walks in with, larger than every tolerance afterwards, and systematic, so the whole analysis stays internally consistent |
45
+ | 27 | `grid-registration` | [024](../traps/024-pixel-is-point/) + [c024](../clean/c024-pixel-is-area/) | easting 412120 from an engine that reads the raw tie point, or 412090 from code that corrects a second time, instead of 412105 | The file says `AREA_OR_POINT=Point`, and GDAL has already folded it into the geotransform (RFC 33). Half a cell is 15 m on a 30 m DEM: smaller than the GPS a crew walks in with, larger than every tolerance afterwards, and systematic. **The truth was 412090 until 2026-09-25, and wrong** — [erratum](../results/README.md#erratum-2026-09-25-trap-024) |
46
46
  | 28 | `hidden-configuration` | [030](../traps/030-sidecar-georeferencing/) + [c030](../clean/c030-single-georeferencing/) | 160000 m2 instead of 40000, and an origin 100 km away | A `.aux.xml` beside a GeoTIFF georeferences it too, and GDAL prefers the sidecar by documented design because that is how a user overrides georeferencing they know to be wrong. Both readings are the library behaving as written; neither answer says which one it used, and one environment variable switches between them |
47
47
  | 29 | `ring-role-by-winding` | [031](../traps/031-hole-wound-as-shell/) + [c031](../clean/c031-hole-wound-as-hole/) | 31000 m2 instead of 29000 — the easement added rather than subtracted | A shapefile carries no nesting: which ring is a hole is decided by the direction it is wound and by nothing else, and GDAL applies that rule as documented (`OGR_ORGANIZE_POLYGONS` defaults to `ONLY_CCW`). An inner ring wound like its parent therefore reads as a second shell, and its area is added. The error flatters the owner by 6.9%, which is smaller than the gap between two surveys of the same field |
48
48
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "argleton"
7
- version = "0.5.0"
7
+ version = "0.6.0"
8
8
  description = "Probes whose right answer is known by construction, and whose wrong answer looks fine"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11" # tomllib, so the runner needs nothing installed