[AZ-515] Extract C10 canonical hash helpers to shared module

Cumulative-review F1 (batches 34-36, carried into batch 37): both
manifest_verifier.py (AZ-324) and provisioner.py (AZ-325) imported
leading-underscore privates _aggregate_tile_hash + _compute_manifest_hash
from manifest_builder.py (AZ-323). The helpers encode the trust-chain
formula shared across all three components; the import shape gave
readers no static signal that a refactor would silently break two
modules.

Move the formula into c10_provisioning/_canonical_hash.py:

- TileHashRecord (moved from manifest_builder)
- aggregate_tile_hash (renamed, public)
- compute_manifest_hash (renamed, public)
- TAKEOFF_ORIGIN_DECIMALS constant (moved)

Callers updated to import directly from _canonical_hash. Bodies
unchanged; manifest hashes are byte-for-byte identical.

Tests: c10_provisioning suite 86/86 pass; full project 1370/1370 pass.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-05-13 05:24:06 +03:00
parent a9c8d60087
commit ca0430a44d
5 changed files with 183 additions and 102 deletions
@@ -32,9 +32,11 @@ from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
from gps_denied_onboard._types.geo import BoundingBox, LatLonAlt
from gps_denied_onboard.clock import Clock
from gps_denied_onboard.components.c10_provisioning._canonical_hash import (
aggregate_tile_hash,
)
from gps_denied_onboard.components.c10_provisioning.manifest_builder import (
TilesByBboxQuery,
_aggregate_tile_hash,
)
from gps_denied_onboard.helpers.sha256_sidecar import Sha256Sidecar
@@ -444,7 +446,7 @@ class ManifestVerifierImpl:
records = tuple(
sorted(records, key=lambda r: (r.zoom, r.lat, r.lon, r.source))
)
computed = _aggregate_tile_hash(records)
computed = aggregate_tile_hash(records)
except Exception as exc:
per_artifact_checks.append(
ArtifactCheck(