mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-06-22 12:11:13 +00:00
[AZ-507] [AZ-323] [AZ-324] C10 Manifest build + verify + AZ-270 hygiene
AZ-507: codify cross-component import rule. Added _types/inference_errors.py shim re-exporting EngineBuildError + CalibrationCacheError from c7_inference; narrowed C10 EngineCompiler's except Exception to the two typed errors so unknown exceptions propagate (AC-3). Rewrote module-layout.md "Imports from" sections for 9 components + added Rule 9; appended an architecture.md ADR-009 note explaining why components must go through _types/*. AZ-323: ManifestBuilder + Ed25519ManifestSigner. Canonical JSON via orjson OPT_SORT_KEYS+OPT_INDENT_2, atomic-write Manifest.json + sha sidecar + .sig via AZ-280, operator-key fingerprint allowlist gate (C10-ST-01), ADR-010 takeoff_origin + flight_id baked into Manifest AND manifest_hash so re-planned routes change the cache identity (AC-15/AC-16). 20 unit tests cover all 16 ACs. AZ-324: ManifestVerifierImpl. Fail-closed Steps A-D: Manifest.json sidecar self-hash, Ed25519 trust-key set, schema parse with absolute/.. path rejection + takeoff_origin in-bbox check, stream SHA-256 per artifact with multi-failure accumulation. Operator mode re-derives tiles_coverage_sha256 from C6; airborne mode trusts the signed aggregate. 19 unit tests cover all 17 ACs. Composition root: c10_factory.build_manifest_builder + build_manifest_verifier + c6_tile_metadata_store_to_tiles_query adapter (the one place that legitimately imports both C6 and C10 without violating the AZ-270 lint). Dependency: pinned cryptography>=43.0,<46.0 in pyproject.toml. Tests: 1300 passed, 80 skipped (env-only), ruff clean for all AZ-323/324 files. AZ-306 (FAISS) intentionally deferred to batch 35 — needs C++ pybind11 toolchain not present in this environment. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,4 +1,8 @@
|
||||
"""C10 `CacheProvisioner` Protocol.
|
||||
"""C10 Public-API Protocols.
|
||||
|
||||
- :class:`CacheProvisioner` (AZ-325, pending) — pre-flight orchestrator.
|
||||
- :class:`ManifestSigner` (AZ-323) — Ed25519 detached signing surface
|
||||
consumed by :class:`ManifestBuilder`.
|
||||
|
||||
Concrete impl: engine compile + descriptors + manifest + content-hash gate. See
|
||||
`_docs/02_document/components/11_c10_provisioning/`.
|
||||
@@ -7,12 +11,58 @@ Concrete impl: engine compile + descriptors + manifest + content-hash gate. See
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Protocol
|
||||
from typing import Protocol, runtime_checkable
|
||||
|
||||
from gps_denied_onboard._types.manifests import Manifest
|
||||
|
||||
__all__ = [
|
||||
"CacheProvisioner",
|
||||
"ManifestSigner",
|
||||
"SigningKeyHandle",
|
||||
]
|
||||
|
||||
|
||||
class CacheProvisioner(Protocol):
|
||||
"""Pre-flight cache provisioning (engine compile + descriptor batch + manifest)."""
|
||||
|
||||
def provision(self, flight_id: str, output_root: Path) -> Manifest: ...
|
||||
|
||||
|
||||
class SigningKeyHandle(Protocol):
|
||||
"""Opaque handle returned by :meth:`ManifestSigner.load_signing_key`.
|
||||
|
||||
The Protocol intentionally exposes no methods — concrete signers
|
||||
(e.g. :class:`Ed25519ManifestSigner`) hold the actual key behind
|
||||
this marker so the caller can pass it back into :meth:`sign` /
|
||||
:meth:`public_key_fingerprint` without ever touching the secret
|
||||
material.
|
||||
"""
|
||||
|
||||
|
||||
@runtime_checkable
|
||||
class ManifestSigner(Protocol):
|
||||
"""Detached-signature provider for :class:`ManifestBuilder` (AZ-323).
|
||||
|
||||
Default impl is :class:`Ed25519ManifestSigner` using
|
||||
``cryptography.hazmat.primitives.asymmetric.ed25519``; tests
|
||||
inject a deterministic in-memory keypair.
|
||||
|
||||
Contract:
|
||||
- :meth:`load_signing_key` takes a path to an operator-supplied
|
||||
PEM-encoded PKCS8 Ed25519 private key, returns an opaque
|
||||
:class:`SigningKeyHandle`. Format errors raise
|
||||
:class:`gps_denied_onboard.components.c10_provisioning.errors.ManifestWriteError`
|
||||
with the underlying ``cryptography`` exception chained via
|
||||
``__cause__``.
|
||||
- :meth:`sign` produces a 64-byte raw Ed25519 signature over the
|
||||
payload bytes. Re-entry-safe; a single handle may be used to
|
||||
sign many payloads.
|
||||
- :meth:`public_key_fingerprint` returns the SHA-256 hex digest of
|
||||
the raw 32-byte public key (operator-mode allowlist key).
|
||||
"""
|
||||
|
||||
def load_signing_key(self, key_path: Path) -> SigningKeyHandle: ...
|
||||
|
||||
def sign(self, key: SigningKeyHandle, payload_bytes: bytes) -> bytes: ...
|
||||
|
||||
def public_key_fingerprint(self, key: SigningKeyHandle) -> str: ...
|
||||
|
||||
Reference in New Issue
Block a user