open-standards/map/CHANGELOG.md
Transaction Science ba1212361f Add aac, map, sandbox standards; catalog the standards family
Commit the previously-untracked standard directories and catalog them in the
root README alongside proof:

- aac/    — communication cargo class: portable boards + a ten-level
            offline-first cascade (Apache-2.0 code / CC-BY-4.0 spec).
- map/    — geospatial cargo class: range-requestable signed tilesets +
            an F0–F4 fidelity cascade (Apache-2.0 code / CC-BY-4.0 spec).
- sandbox/— isolated, metered, attested execution across the heterogeneous
            compute fabric (Apache-2.0 code / CC-BY-4.0 spec).
- jouleclaw-otel-authz, jouleclaw-trust — new jouleclaw reference crates.

Root README now lists aac, map, sandbox, and proof in the catalog, the tree,
and the contribution guide.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-07 17:04:36 -04:00

144 lines
9.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Changelog — Map
All notable changes to the Map standard and its reference implementation.
Format follows Keep a Changelog; the standard versions independently of the
reference crates (which share the `map-rs` workspace version).
## [0.1.0] — 2026-06-04
Initial draft standard — the protocol spine.
### Added
- **Specification.** `SPEC.md` (RFC 2119) defining the tile cargo, the 4D cell
key, canonical serialization + content addressing, the range-requestable
tileset + signed manifest/revision chain, the F0–F4 fidelity cascade, and the
JCR-1 receipt. Sub-specs under `spec/`.
- **`map-schema`** — `CellKey` (S2 + altitude band + time bucket + LOD),
`ContentId`, `Tile`, `Directory` (Hilbert-sorted + range planner), `Manifest`,
`Revision`, `verify_chain`, and the `Tier` enum.
- **`map-cascade`** — `resolve` over a `TileSource`, returning the highest tier
≤ the request with a guaranteed F1 fallback.
- **`map-receipt`** — `Receipt`, `Energy`, `Provenance`, JCR-1 sealing/verifying
(vendored, byte-compatible with the family verifiers).
- **`map-conformance`** — C1–C5 + C-neg harness (all checks real) and the
`gen-vectors` generator; published vectors in `conformance/v1/`.
- **Vocabulary.** `vocab/v1.ttl`, `v1.jsonld`, `v1.shapes.ttl`, `LEXICON.md`.
- **`map-index`** — pure-Rust S2 cell geometry (cell ids, projection, lat/lng,
points, edges, polygons, regions/caps/rects, the region coverer, metrics)
ported from `joule-s2`, plus a `bridge` to `map-schema`: `cell_key` from
coordinates, and `cover_region`/`cover_viewport` from a cap, rectangle, or
**polygon** to sorted `CellKey`s feeding the directory range planner. 75 tests,
zero clippy warnings.
- **Fixed (vs. upstream `joule-s2`)** the `polygon` module, which failed its own
tests upstream: spherical point-in-polygon now uses an orientation-robust
winding-angle test (was a degenerate ray); area uses the van Oosterom–Strackee
signed-area fan (was Girard's-formula complement, ≈4π−A); and `S2Polygon` now
implements `S2Region`, so the coverer accepts arbitrary boundaries / footprints
/ geofences.
- **`map-index::volume`** — the recommended 4D discretization scheme ported from
`joule-spatial3d`: logarithmic `AltBand`s (Mariana Trench → cislunar),
logarithmic `TimeTier`/`TimeBucket`s (1 s → 100 yr), `SpaceTimePoint`,
`SpatialKey`, and the `Spatial3DIndex`/`PositionRingBuffer` runtime utilities.
New bridge functions `alt_band`, `time_bucket`, and `cover_volume` map the
scheme into `map-schema` `CellKey`s and cover a horizontal region × altitude
range × time range. (The `chrono` convenience constructors were dropped to keep
the reference dependency-light.)
- **`map-tiles`** — tile payload codecs ported from `joule-tiles`: MVT vector,
raster (PNG/WebP), terrain quantized-mesh, and 3D Tiles, with no S2/geo or
routing dependency. A `tile` bridge wraps each as a content-addressed
`map-schema` `Tile` at its cascade tier — terrain → `F1`, raster → `F2`, MVT +
b3dm → `F3`, splat → `F4` — with stable `codec` tags.
- **`map-tiles` splat codec** (`map_tiles::splat`) — the `F4:Photoreal` cargo
codec the tier was missing: a compact SPZ-style container for 3D Gaussian splats
(positions fixed-point, scales log-quantized, rotation quaternion + colour as
bytes, gzip-compressed), with `encode_splats`/`decode_splats`. **Spherical
harmonics**: encodes degree-`n` view-dependent colour as `(n+1)²−1` quantized
RGB coefficients above the DC term (`sh_degree` in the header). Round-trip
(incl. degree-1 SH) + compression tests.
- **`map-tiles` PLY ingest** (`map_tiles::splat::read_ply`) — reads the de-facto
**INRIA `.ply`** 3DGS interchange format (ASCII + binary-little-endian),
inverting the trainer's storage conventions (log-scales → `exp`, logit-opacity
→ `sigmoid`, `(w,x,y,z)` → `(x,y,z,w)` normalized, DC `= 0.5 + C₀·f_dc`,
channel-major `f_rest` → per-coefficient SH) into `Splat`s that `encode_splats`
re-encodes into a conforming F4 tile. ASCII + binary + rejection tests.
- **`map-tiles` b3dm / glTF decode** (`map_tiles::tiles3d::read_b3dm`, `read_glb`)
— the reader half of the 3D Tiles codec: strips the b3dm header + feature/batch
tables and decodes the embedded binary glTF (GLB) into a triangle mesh, general
over accessors/bufferViews (f32 VEC3 positions; u8/u16/u32 indices; accessor +
bufferView byte offsets and strides; multi-primitive merge). Round-trips
`B3dmBuilder::encode`; encode/decode + u16-index + rejection tests.
- **`map-serve` crate** — a transport-agnostic tile-serving core (no HTTP-framework
dependency): `serve(store, steward, req)` parses a tile request, resolves it
through the F0–F4 cascade, and returns a content-addressed `Response` with a
strong `ETag`, `Cache-Control: immutable`, `If-None-Match` → `304`, `X-Map-Tier`
/ fell-back, and a JCR-1 energy-receipt header. Includes a `MemoryStore`
reference `TileServer`, plus a filesystem `DirStore` (content-addressed blobs on
disk + a reloadable JSON index; `std`-only). Pure + unit-tested with a runnable
doctest.
- **`map-serve-axum` crate** — an axum/tokio HTTP binding for the serving core:
`router(store, steward)` exposes `serve` as an axum `Router`, `run(addr, …)` is a
one-call server. The async stack is isolated here so `map-serve` stays
framework-free. Verified by `oneshot` tests and a live-socket demo over real HTTP.
- **`map-route` turn-by-turn + isochrones** — `directions::turn_by_turn` derives
human maneuvers (depart with cardinal heading, slight/normal/sharp turns,
U-turn, arrive) from route-segment bearing deltas, merging straight runs into
one step; `isochrone::isochrone` computes the budget-bounded reachable set from
a source by travel time or distance (Dijkstra expansion with pruning). Both
unit-tested.
- **`map-route` multi-modal + traffic-aware costs** — a `CostModel` trait and a
built-in `ModeProfile` (car/bicycle/foot) with per-mode road-class access
matrices, free-flow speeds, and a congestion multiplier; `cost::find_route_with`
is a generalized A* (admissible time heuristic) that skips inaccessible edges
and reports mode-specific durations. `RoadType` is now `Copy`. Unit-tested
(mode access, highway avoidance on foot, traffic slowdown).
- **`map-route` public-transit routing** (`transit`) — the Connection Scan
Algorithm over a GTFS-like `Timetable`: earliest arrival from timetabled
`Connection`s with walking-footpath transfers (manual or auto-generated within a
radius), reconstructing ride/walk `Leg`s. Times are integer seconds. Unit-tested
(line with wait, missed connection, faster-of-two, footpath transfer, auto-transfers).
- **`map-tiles` MVT decoder** — added the reader half (`mvt::decode_tile`,
`decode_geometry`, `unzigzag`): a minimal protobuf reader inverse to the
encoder, plus the geometry-command decoder back to absolute tile-local rings /
line-strings. A conforming reader must decode to render; the encoder shipped
without it. Encode→decode roundtrip tests cover geometry + properties + closed
polygons. (Not in upstream `joule-tiles`.)
- **Real-world robustness fix:** `decode_value` now handles MVT `sint_value`
(field 6, zigzag), decodes `int_value` (field 4) as a plain varint per spec
(was wrongly zigzag), and tolerates an empty/unknown value instead of aborting
the whole tile. Verified by decoding live OpenMapTiles tiles (OpenFreeMap) —
previously failed with `ProtobufError("empty value")`.
- **Fixed (vs. upstream `joule-tiles`)** `mvt::encode_polygon`, which clobbered
the `CMD_MOVE_TO` command word with a coordinate and reset the geometry cursor
per ring (malformed multi-ring polygons); added the missing regression test.
Backported to `joule-tiles`.
- **`map-orbital`** — TLE parsing, SGP4/SDP4 propagation, and ECI/ECEF/geodetic
transforms ported from `joule-orbital` (no `tracing` dependency; only the
doctest referenced it). A `bridge` maps a propagated satellite sub-point to a
`map-schema` `CellKey` — S2 cell at the sub-point, the altitude band for its
altitude (the ISS lands in the LEO band), and the time bucket for the instant —
so a live satellite is an `F3` address on the same 4D grid as every tile. Lint
cleanups only; the 38 SGP4/SDP4 known-answer tests confirm the numerics are
unchanged.
- **`map-route`** — local geospatial capabilities over a tileset, ported from
`joule-maps` (energy metering, tile cache, and the in-memory store dropped —
redundant with `map-receipt`/`map-tiles`/`map-schema`): WGS84 geometry,
haversine/bearing/midpoint, point-in-polygon, POI geocoding, Dijkstra + A*
routing on a weighted graph, and polygon geofencing. Added a **feed-agnostic
adapter** (`feed::{Entity, Feed}`): any source — flights, vessels, satellites,
CVEs, incidents, supply-chain nodes, enterprise signals — resolves to a
`CellKey`, so "swap the feeds and it visualizes anything with a location or a
time" is a property of the standard, not a per-feed rewrite. Tests cover the
ported geocode/route/geofence/geometry paths (the upstream tests did not come
with the extracted subset).
- **`map-schema`** — `TimeBucket.width_ms` widened `u32 → u64` so the temporal
axis can express coarse archival buckets (a year, a century); `u32` capped it
at ~49 days. CBOR encodes integers by magnitude, so existing content ids and
conformance vectors are byte-identical.
### Notes
- The remaining substrate crates (`map-index` 4D layer from `joule-spatial3d`,
`map-tiles`, `map-orbital`, `map-route`) and the demonstrator's `wgpu` renderer
are not yet in this release — see [`ROADMAP.md`](ROADMAP.md).