mapsmith 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.
- {mapsmith-0.5.0 → mapsmith-0.6.0}/.zenodo.json +1 -1
- {mapsmith-0.5.0 → mapsmith-0.6.0}/CHANGELOG.md +174 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/CITATION.cff +2 -2
- {mapsmith-0.5.0 → mapsmith-0.6.0}/PKG-INFO +181 -116
- {mapsmith-0.5.0 → mapsmith-0.6.0}/README.md +180 -115
- {mapsmith-0.5.0 → mapsmith-0.6.0}/SECURITY.md +13 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/docs/catalog-entry-spec.md +6 -6
- {mapsmith-0.5.0 → mapsmith-0.6.0}/docs/manifest-vocabulary.md +13 -7
- {mapsmith-0.5.0 → mapsmith-0.6.0}/examples/01_verified_geoprocessing.ipynb +26 -26
- {mapsmith-0.5.0 → mapsmith-0.6.0}/examples/02_terrain_hydrology.ipynb +36 -36
- {mapsmith-0.5.0 → mapsmith-0.6.0}/examples/03_validated_plans.ipynb +24 -31
- {mapsmith-0.5.0 → mapsmith-0.6.0}/funding.json +1 -1
- {mapsmith-0.5.0 → mapsmith-0.6.0}/pyproject.toml +1 -1
- {mapsmith-0.5.0 → mapsmith-0.6.0}/server.json +3 -3
- {mapsmith-0.5.0 → mapsmith-0.6.0}/site/build.py +115 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/site/index.template.html +142 -31
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/__init__.py +1 -1
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/antimeridian.py +125 -8
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/catalog.py +56 -2
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/engines/dispatch.py +24 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/engines/duckdb_engine.py +23 -20
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/engines/raster.py +152 -130
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/engines/sampling.py +12 -6
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/engines/vector.py +598 -206
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/engines/whitebox_engine.py +174 -139
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/plans/registry.py +14 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/provenance.py +58 -39
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/conftest.py +22 -1
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/data/manifest-v1.schema.json +25 -3
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/data/manifest_spec_validator.py +76 -38
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_datum.py +276 -3
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_discovery_report.py +149 -114
- mapsmith-0.6.0/tests/test_failure_manifest.py +247 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_lineage.py +4 -3
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_raster_reproject_bands.py +176 -103
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_showcase.py +270 -2
- mapsmith-0.6.0/tests/test_summarize_points_in_polygons.py +667 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_verify.py +52 -5
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_whitebox_derivatives.py +41 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/.dockerignore +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/.gitignore +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/CLAUDE.md +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/CONTRIBUTING.md +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/Dockerfile +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/LICENSE +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/MANIFESTO.md +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/TRADEMARKS.md +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/docker-compose.yml +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/docs/argleton-run.json +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/docs/benchmarks.md +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/examples/README.md +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/examples/fixtures/mount_st_helens_dem.tif +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/glama.json +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/schema/operation.schema.json +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/datum.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/discovery_log.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/engines/__init__.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/engines/esri.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/engines/geodesy.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/engines/linework.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/engines/network.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/engines/sedona_engine.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/engines/spatial_stats.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/engines/summaries.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/gdal_policy.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/grid.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/jobs.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/lineage.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/plans/__init__.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/plans/executor.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/plans/models.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/plans/validator.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/preview.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/readers.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/retrieval.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/server.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/sql_policy.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/stacks.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/ui.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/verify.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/src/mapsmith/workspace.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/data/discovery_queries.json +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_ambiguous_layer.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_antimeridian.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_band_math.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_catalog.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_catalog_applicability.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_catalog_entry_spec.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_catalog_retrieval.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_centroid_convert.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_clip_reclassify_raster.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_contours_and_cost.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_dashboard.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_describe_raster.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_discovery_contract.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_discovery_log.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_duckdb_sandbox.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_engines.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_environment.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_gdal_policy.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_geodesy.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_geoparquet2.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_grid_registration.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_linework.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_measure_area.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_merge_simplify.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_nearest_explode.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_network.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_overlay_dissolve.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_path_containment.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_plans.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_preview.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_published_figures.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_raster.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_redaction.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_resample_raster.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_retrieval.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_retrieval_at_scale.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_retrieval_degradation.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_sampling.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_select_and_extract.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_smoke.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_south_up_and_mixed.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_spatial_stats.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_sql_axis_order.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_sql_credentials.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_stacks.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_summaries.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_terrain_derivatives.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_tier_a_operations.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_ui.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_verification_status.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_verify_repair.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_voronoi.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_whitebox.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_whitebox_encoding.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_whitebox_geographic_refusal.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_worked_example.py +0 -0
- {mapsmith-0.5.0 → mapsmith-0.6.0}/tests/test_workspace.py +0 -0
|
@@ -8,6 +8,180 @@ All notable changes to MapSmith are documented here, in the format of
|
|
|
8
8
|
|
|
9
9
|
Nothing yet.
|
|
10
10
|
|
|
11
|
+
## [0.6.0] - 2026-09-25
|
|
12
|
+
|
|
13
|
+
The reason to upgrade is in **Fixed**: five operations stop reading a zone drawn
|
|
14
|
+
across the 180th meridian as the rest of the planet, `nearest_join` stops
|
|
15
|
+
measuring distances there 5-6% too long, and 28 writers stop leaving a dataset
|
|
16
|
+
with no manifest when they fail. The reason to read before upgrading is in
|
|
17
|
+
**Changed**: one manifest key is renamed.
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- **Two cases on [mapsmith.dev](https://mapsmith.dev/#step-through) that a reader
|
|
22
|
+
steps through**, both executed while the page is built. One is a whole
|
|
23
|
+
analysis: the question in plain words, the catalogue narrowing with the counts
|
|
24
|
+
it produced, a plan refused before anything ran, five steps with their engine,
|
|
25
|
+
CRS decision and checks read from the manifests, the answer, and the chain
|
|
26
|
+
recovered from the final file alone. The other is a refusal — a GeoTIFF that
|
|
27
|
+
opens in every viewer, carrying its georeferencing twice and disagreeing with
|
|
28
|
+
itself, declined with a message naming both readings and how to choose.
|
|
29
|
+
|
|
30
|
+
Nothing in the installable product changed. The script is progressive: every
|
|
31
|
+
beat ships as ordinary HTML and the script only hides them and adds a button,
|
|
32
|
+
so the page reads in full with JavaScript off.
|
|
33
|
+
|
|
34
|
+
You pick the question, not the data, and that is a security decision rather
|
|
35
|
+
than a limitation: an upload box would mean running GDAL on files from
|
|
36
|
+
strangers, which is the assumption `SECURITY.md` is built on refusing.
|
|
37
|
+
|
|
38
|
+
- **`summarize_points_in_polygons`**: a numeric attribute of the points in each
|
|
39
|
+
polygon — count, sum, mean, median, min, max, stdev, range. "Average pH by
|
|
40
|
+
field block" used to take two operations, which to somebody searching is an
|
|
41
|
+
operation that does not exist. Three decisions about the number are in the
|
|
42
|
+
record: a polygon with no points is kept with its statistics null, because
|
|
43
|
+
the mean of no values is not zero; a point with no value is placed and not
|
|
44
|
+
summarised, so `<field>_count` can be smaller than `point_count` and says so;
|
|
45
|
+
and the boundary rule is the caller's, with the number of points it counted
|
|
46
|
+
twice or dropped. A check reads the output back and verifies the counts add
|
|
47
|
+
up to what the join found. Points only: a MultiPoint is refused rather than
|
|
48
|
+
carried whole into every polygon it touches, and a Shapefile output is
|
|
49
|
+
refused where the driver would truncate a column into the attribute's own
|
|
50
|
+
name. Reached through `run_operation`; the tool count is unchanged.
|
|
51
|
+
|
|
52
|
+
### Changed
|
|
53
|
+
|
|
54
|
+
- **Records declare `spec_version` `1.0.0-draft.6`, and `x-mapsmith:round_trip`
|
|
55
|
+
is now `round_trip`.** Breaking for anyone who reads that key. The
|
|
56
|
+
specification gained a core key for "computed in another CRS and written back
|
|
57
|
+
in the caller's", with the two legs MapSmith already recorded, and draft.6
|
|
58
|
+
forbids recording that fact under a prefixed name: two producers naming the
|
|
59
|
+
same fact differently is two facts to a consumer. The shape is unchanged —
|
|
60
|
+
`transformation` for the way out, `return_transformation` for the way back —
|
|
61
|
+
so a reader needs to change the key it looks up and nothing else.
|
|
62
|
+
|
|
63
|
+
### Fixed
|
|
64
|
+
|
|
65
|
+
- **`count_in_polygons(predicate="contains")` never placed a point, and said it
|
|
66
|
+
had verified.** `sjoin(points, polygons, predicate)` evaluates the predicate
|
|
67
|
+
as `predicate(point, polygon)`, so `contains` asked whether a point contains
|
|
68
|
+
a polygon — false for any polygon with area. Every count came back zero, the
|
|
69
|
+
record said `verified: true`, and the one check that noticed was
|
|
70
|
+
non-critical and blamed the points for lying outside every polygon. Even the
|
|
71
|
+
reading that was meant, the polygon containing the point, is exactly
|
|
72
|
+
`within`. `contains` is refused now, with the two predicates that mean
|
|
73
|
+
something for points; a caller using it was getting zeros, so nothing that
|
|
74
|
+
worked stops working. Found while building its sibling above, which had
|
|
75
|
+
inherited the same line.
|
|
76
|
+
- **`count_in_polygons` counted a MultiPoint once in every polygon it touched,
|
|
77
|
+
and blamed the polygons for points that had no position.** Both measured
|
|
78
|
+
before the fix: a MultiPoint straddling two squares came back as one point in
|
|
79
|
+
each, and a null and an empty geometry were reported as "2 of 3 points fall
|
|
80
|
+
in no polygon" with a hint about checking the boundaries. Multi-part and
|
|
81
|
+
areal geometries are refused now, with the way out; points without a
|
|
82
|
+
geometry are counted apart as `points_without_geometry` and no longer fail
|
|
83
|
+
the placement check.
|
|
84
|
+
- **A zone drawn across the 180th meridian as one ring counted the wrong
|
|
85
|
+
points, and the total could be right.** Every planar library reads such a
|
|
86
|
+
ring as its complement, the rest of the planet. Measured with two points, one
|
|
87
|
+
at 175°E inside the zone and one at 0°: the first was dropped, the second
|
|
88
|
+
counted, and the total was 1 — the same as the truth. Both point-in-polygon
|
|
89
|
+
operations now refuse that ring with the way out (split it at 180, as RFC
|
|
90
|
+
7946 §3.1.9 prescribes, which then places correctly). The detector is in
|
|
91
|
+
`antimeridian.naive_crossings` and only looks at layers in degrees.
|
|
92
|
+
Measured the same way on the other region operations before extending it:
|
|
93
|
+
`clip_layer`, `spatial_join` and `overlay_layers` each returned the feature
|
|
94
|
+
on the far side of the world instead of the one inside the zone, and
|
|
95
|
+
`nearest_join` returned nothing; all four refuse that ring now, on either
|
|
96
|
+
input, and `spatial_join` on every engine — GeoParquet in one CRS is routed
|
|
97
|
+
to DuckDB or SedonaDB, which read the ring the same planar way. `measure_area`
|
|
98
|
+
is not affected — its geodesic area follows the edge the short way — and is
|
|
99
|
+
left alone.
|
|
100
|
+
|
|
101
|
+
What is **not** refused, because it is not the defect: an edge that runs
|
|
102
|
+
from -180 to 180 along the edge of the plane. That is how a rectangle
|
|
103
|
+
covering the world, a latitude band, a polar cap and Antarctica in the
|
|
104
|
+
Natural Earth countries file close their rings, and a first version of the
|
|
105
|
+
detector refused all four — so "points per country" would have been refused.
|
|
106
|
+
Found by the pre-release review, and the Natural Earth file is a test now.
|
|
107
|
+
- **`nearest_join` measured distances 5-6% too long across the antimeridian,
|
|
108
|
+
with no warning.** It works in an estimated UTM zone, and GeoPandas centres
|
|
109
|
+
that estimate on the mean of `minx` and `maxx`: for data straddling 180 that
|
|
110
|
+
is about 0, so two points at 175°E and 175°W were given EPSG:32630, centred on
|
|
111
|
+
3°W. Their distances to a zone three degrees away came back as 351.7 and
|
|
112
|
+
354.0 km where the truth is 334.0. `antimeridian.estimate_utm_crs` centres on
|
|
113
|
+
the true extent instead (here UTM 1N, within one per cent), and returns
|
|
114
|
+
exactly what GeoPandas does for data that `describe_dataset` does not report
|
|
115
|
+
as crossing. That definition is wider than touching 180: points at 100°E and
|
|
116
|
+
170°W are closer going across it, and now get UTM 55N, centred on 147°E,
|
|
117
|
+
where GeoPandas gave 25N, centred on 33°W. A layer split at 180 as a single MultiPolygon, the
|
|
118
|
+
form the refusal above asks for, is read part by part and counts as crossing.
|
|
119
|
+
`buffer_layer`, `simplify_layer` and `centroid_layer` use it too; a 1 km
|
|
120
|
+
buffer had measured correctly even in the far zone, so for them it is the
|
|
121
|
+
right zone rather than a fix.
|
|
122
|
+
|
|
123
|
+
- **Five operations wrote a fact into the manifest before it happened.** The
|
|
124
|
+
record survives a crash, which is the point of it, and on these paths it
|
|
125
|
+
survived carrying a sentence that had become false.
|
|
126
|
+
- `simplify_layer`, `centroid_layer` and `nearest_join` recorded the round
|
|
127
|
+
trip before the way back ran, and the way back runs inside the block that
|
|
128
|
+
writes the record on failure. A return leg that raised left a manifest
|
|
129
|
+
asserting a trip that never finished. `buffer_layer` had the right order
|
|
130
|
+
by accident. The trip is recorded only once the output is home, and
|
|
131
|
+
draft.6 now requires exactly that of every producer.
|
|
132
|
+
- `reproject_layer` and `reproject_raster` recorded `target_crs` and the
|
|
133
|
+
transformation before any coordinate moved, so a failed reprojection said
|
|
134
|
+
where the data had been put and by which operation — with a seven-metre
|
|
135
|
+
datum shift, on a NAD27 input, beside geometry that had not gone anywhere.
|
|
136
|
+
- Three `reason` strings said "output geometries are returned in the input
|
|
137
|
+
CRS", written before the work and surviving on the failing path while the
|
|
138
|
+
key correctly disappeared. The key says it now, when it is true.
|
|
139
|
+
- **`reproject_raster` could leave a raster with no manifest beside it.** A
|
|
140
|
+
warp that raised on the second of three bands left a 19608-byte file on disk
|
|
141
|
+
— band one warped, two and three zero-filled — and nothing describing it.
|
|
142
|
+
The write is inside the failure audit now, and a partial file carries a
|
|
143
|
+
record that says `x-mapsmith:operation_completed: false`.
|
|
144
|
+
- **The same defect was in 28 of the 58 writers 0.5.1 shipped, found by
|
|
145
|
+
looking for it everywhere instead of where it had last been seen.** A write
|
|
146
|
+
that died halfway, or a check that raised after the output reached the disk,
|
|
147
|
+
left the dataset with nothing beside it: in `resample_raster` — the twin of
|
|
148
|
+
the operation above — and in the thirteen Whitebox operations, `run_sql`,
|
|
149
|
+
five more raster operations (`reproject_raster` among them, whose write was
|
|
150
|
+
covered and whose reading-back was not), both sampling operations and six
|
|
151
|
+
vector ones. Every writer now holds the net from its first byte to its
|
|
152
|
+
manifest, and `tests/test_failure_manifest.py` injects both failures into
|
|
153
|
+
every writing operation the catalogue lists. Run against the code just
|
|
154
|
+
before this change, it fails on those 28 and on one more,
|
|
155
|
+
`summarize_points_in_polygons`, which had inherited the shape before it ever
|
|
156
|
+
shipped — and on no other.
|
|
157
|
+
|
|
158
|
+
### Security
|
|
159
|
+
|
|
160
|
+
- **No workflow job that runs this repository's code can mint an OIDC token.**
|
|
161
|
+
The MCP Registry grants `io.github.mapsmith-ai/*` to a token from any
|
|
162
|
+
workflow of this owner. The site workflow granted `id-token: write` to all
|
|
163
|
+
its jobs, including the one that runs `pip install` and our own build
|
|
164
|
+
scripts; only the deploy job, which runs one pinned action, holds it now.
|
|
165
|
+
The new registry workflow publishes a tag only if its commit is on `main` and
|
|
166
|
+
its own CI run passed — a dry run on `v0.5.0`, whose CI failed, stops there.
|
|
167
|
+
|
|
168
|
+
## [0.5.1] - 2026-09-21
|
|
169
|
+
|
|
170
|
+
### Fixed
|
|
171
|
+
|
|
172
|
+
- **0.5.0 is yanked on PyPI, and the reason is its own page.** The release
|
|
173
|
+
procedure builds and uploads only after the tag's CI is green, because that
|
|
174
|
+
run is the one that checks the README against the release it claims to
|
|
175
|
+
describe. The upload went first: PyPI took the sdist whose front page says
|
|
176
|
+
*"This page describes 0.4.0"* and *"`main` is ahead of 0.4.0 today"*, and a
|
|
177
|
+
PyPI page cannot be edited afterwards. The code in 0.5.0 is the code here;
|
|
178
|
+
what is wrong is the artefact describing itself as the previous version, on
|
|
179
|
+
a product whose argument is that records describe what they say they do.
|
|
180
|
+
0.5.1 is 0.5.0 with that paragraph correct.
|
|
181
|
+
|
|
182
|
+
Nothing else moved: records still declare `spec_version` `1.0.0-draft.5`, the
|
|
183
|
+
tool surface is the same, and the entries below are this release's.
|
|
184
|
+
|
|
11
185
|
## [0.5.0] - 2026-09-21
|
|
12
186
|
|
|
13
187
|
Everything here was on `main` and not in a release. It is almost entirely
|
|
@@ -12,8 +12,8 @@ identifiers:
|
|
|
12
12
|
value: "10.5281/zenodo.22213091"
|
|
13
13
|
description: "Concept DOI — always resolves to the latest release"
|
|
14
14
|
license: AGPL-3.0-or-later
|
|
15
|
-
version: "0.
|
|
16
|
-
date-released: "2026-09-
|
|
15
|
+
version: "0.6.0"
|
|
16
|
+
date-released: "2026-09-25"
|
|
17
17
|
keywords:
|
|
18
18
|
- GIS
|
|
19
19
|
- geospatial
|