[AZ-343] C2.5 InlierCountReRanker + shared FeatureExtractor helper

Implements the production-default ReRankStrategy: K=10 → N=3 by
single-pair LightGlue inlier count, with strict drop-and-continue
(INV-8) on per-candidate TileFetch / backbone / zero-inlier failures
and RerankAllCandidatesFailedError on zero survivors. Composition
root injects the shared LightGlueRuntime + Clock + the new
FeatureExtractor helper (an L1 placeholder OpenCvOrbExtractor that
unblocks AZ-343 and future C3 strategies — task scope expansion).

Architectural notes:
- Cross-component imports stay banned; tile_store types as `object`
  and the C6 TileCacheError family is duck-typed by class module
  prefix (same workaround AZ-348 adopted for c7_inference; proper
  fix is to relocate TileCacheError to _types/ in a follow-up).
- Clock injection follows the replay contract (AZ-398 Invariant 2);
  reranked_at is sourced from clock.monotonic_ns().
- AZ-342 factory grew `feature_extractor` + `clock` + `fdr_client`
  parameters; existing AZ-342 conformance tests updated.

Tests: 19 new AC-1..AC-12 + mixed-failure scenarios in
test_inlier_count_reranker.py; existing AZ-342 suite (26) still
green. Full repo sweep 1093 passed / 2 skipped (cmake/actionlint
not on PATH).

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-05-12 06:22:40 +03:00
parent 9a605c8514
commit 48ea1e2fc2
10 changed files with 1739 additions and 13 deletions
@@ -28,12 +28,15 @@ from typing import TYPE_CHECKING
from gps_denied_onboard.runtime_root.errors import StrategyNotAvailableError
if TYPE_CHECKING:
from gps_denied_onboard.clock import Clock
from gps_denied_onboard.components.c2_5_rerank import (
C2_5RerankConfig,
ReRankStrategy,
)
from gps_denied_onboard.components.c6_tile_cache import TileStore
from gps_denied_onboard.config.schema import Config
from gps_denied_onboard.fdr_client import FdrClient
from gps_denied_onboard.helpers.feature_extractor import FeatureExtractor
from gps_denied_onboard.helpers.lightglue_runtime import LightGlueRuntime
__all__ = ["build_rerank_strategy"]
@@ -71,6 +74,9 @@ def build_rerank_strategy(
*,
tile_store: "TileStore",
lightglue_runtime: "LightGlueRuntime",
feature_extractor: "FeatureExtractor",
clock: "Clock",
fdr_client: "FdrClient | None" = None,
) -> "ReRankStrategy":
"""Construct the :class:`ReRankStrategy` impl selected by config.
@@ -79,15 +85,27 @@ def build_rerank_strategy(
raises :class:`StrategyNotAvailableError` BEFORE any import.
3. Lazily imports the concrete strategy module.
4. Constructs the strategy via its module-level
``create(config, tile_store, lightglue_runtime)`` factory
function (each concrete strategy module exports ``create`` as
its public entry-point; concrete constructors stay private).
``create(config, tile_store, lightglue_runtime, feature_extractor, fdr_client)``
factory function (each concrete strategy module exports
``create`` as its public entry-point; concrete constructors
stay private).
5. Emits ONE INFO log ``kind="c2_5.rerank.strategy_loaded"`` with
structured fields ``{strategy, top_n}``.
``feature_extractor`` is a shared L1 helper (AZ-343 scope
expansion) used by the concrete strategy to extract keypoints +
descriptors from each per-frame nav image AND from each
candidate's tile pixels. ``clock`` is the composition-root
:class:`Clock` (AZ-398) — strategies stamp
:attr:`RerankResult.reranked_at` via ``clock.monotonic_ns()``
rather than calling stdlib ``time`` directly (Invariant 2 of
the replay contract). ``fdr_client`` is optional — passed
through to strategies that emit FDR records; ``None`` lets the
strategy run without FDR emission (useful for tests).
Raises:
StrategyNotAvailableError: compile-time flag OFF or
concrete module not yet built (AZ-343 pending).
concrete module not yet built.
"""
block = _c2_5_config(config)
strategy = block.strategy
@@ -128,12 +146,18 @@ def build_rerank_strategy(
config,
tile_store=tile_store,
lightglue_runtime=lightglue_runtime,
feature_extractor=feature_extractor,
clock=clock,
fdr_client=fdr_client,
)
else:
instance = create_fn(
config,
tile_store=tile_store,
lightglue_runtime=lightglue_runtime,
feature_extractor=feature_extractor,
clock=clock,
fdr_client=fdr_client,
)
_LOG.info(
"c2_5.rerank.strategy_loaded",