Files
Oleksandr Bezdieniezhnykh a1185d0a28 [AZ-345] [AZ-346] [AZ-347] [AZ-349] C3 matchers + C3.5 AdHoP refiner
Implement the three concrete C3 CrossDomainMatcher strategies plus the
C3.5 production-default AdHoPRefiner.

C3 (AZ-345/346/347):
- DiskLightGlueMatcher + AlikedLightGlueMatcher share a single shared
  _pipeline.run_lightglue_pipeline orchestrator (decode -> query
  extract -> per-candidate loop -> RANSAC sort -> health update ->
  FDR emit) so the only per-backbone delta is the keypoint+descriptor
  extractor closure. ALIKED adds a create-time engine output-schema
  probe (AC-special-1).
- XFeatMatcher owns its own per-candidate loop (single forward fuses
  extraction + matching); it re-uses the shared FDR emission helpers
  to keep telemetry byte-identical across strategies. lightglue_runtime
  parameter accepted by factory but discarded (AC-special-1).
- All three consume the shared LightGlueRuntime / RansacFilter /
  RollingHealthWindow helpers; no helper forks. InferenceRuntimeCut
  consumer-side Protocol added per AZ-507.

C3.5 (AZ-349):
- AdHoPRefiner implements the <= conditional gate, runs the OrthoLoC
  AdHoP TRT engine over best-candidate correspondences, re-runs RANSAC
  on the perspective-preconditioned set, and emits an enriched
  MatchResult with refinement_label="adhop".
- Invariant 4 passthrough fall-through: any RefinerBackboneError (TRT
  failure, OOM, NaN, bad shape) is caught, logged ERROR, FDR-emitted
  with error: true, and converted to passthrough that still counts
  against the rolling invocation-rate window. MemoryError and other
  non-listed exceptions propagate by design (AC-5 closed-set
  semantics).
- Rolling 60-s invocation-rate window + rate-limited WARN log
  (configurable via ratelimited_warn_window_ns; default 60 s).

Shared changes:
- C3MatcherConfig + C3_5RefinerConfig extended with the new
  weights/threshold/window fields.
- matcher_factory + refiner_factory optionally forward clock +
  fdr_client to the strategy's create(); backward-compatible.
- fdr_client.records registers five new kinds: matcher.frame_done,
  matcher.backbone_error, matcher.insufficient_inliers,
  matcher.all_failed, refiner.frame_done.

Tests: 66 new (43 C3 parametrised + 23 AdHoP) covering 47/47 ACs;
focused suite green; full project test suite green except for one
pre-existing flaky CLI cold-start timing test unrelated to this batch.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-14 04:09:22 +03:00

6.6 KiB
Raw Permalink Blame History

Batch 57 — Cycle 1 Report

Date: 2026-05-14 Tasks: AZ-345 (DISK+LightGlue), AZ-346 (ALIKED+LightGlue), AZ-347 (XFeat), AZ-349 (AdHoP refiner) Verdict: COMPLETE — PASS_WITH_WARNINGS

Summary

Implemented the three concrete C3 CrossDomainMatcher strategies plus the C3.5 production-default AdHoPRefiner. All four wire into the existing AZ-344 / AZ-348 factories via module-level create(...) entry points and consume the shared LightGlueRuntime (AZ-285) / RansacFilter (AZ-282) / RollingHealthWindow helpers — no helper forks. The DISK + ALIKED strategies share a single _pipeline.run_lightglue_pipeline orchestrator (decode → query extract → per-candidate loop → RANSAC sort → health update → FDR emit) so the only per-backbone delta is the keypoint+descriptor extractor closure. XFeat owns its own per-candidate loop because its backbone fuses extraction + matching into one forward pass — but it re-uses the shared FDR emission helpers verbatim so all four strategies produce byte-identical telemetry shapes.

The AdHoP refiner implements the conditional gate at exact <= semantics (Invariant 3), runs the OrthoLoC AdHoP TRT engine over the best-candidate correspondences, re-runs RANSAC on the perspective-preconditioned set, and emits an enriched MatchResult with refinement_label="adhop". Invariant 4 passthrough fall-through is preserved: any RefinerBackboneError (TRT failure, OOM, NaN, bad shape) is caught, logged at ERROR, FDR-emitted with error: true, and converted to a passthrough that still counts against the rolling invocation-rate window. MemoryError and other non-listed exception types propagate by design (AC-5 closed-set semantics).

Closes the AZ-345/346/347/349 dependency block. The next downstream consumer in cycle 1 is the e2e pipeline wiring (C3 + C3.5 → pose-estimator) which now has all four strategies available at runtime.

Files added / modified

Added (9)

  • src/gps_denied_onboard/components/c3_matcher/disk_lightglue.pyDiskLightGlueMatcher + module-level create. Hard-coded preprocessor (NCHW float32 RGB 480×480 ImageNet-normalised).
  • src/gps_denied_onboard/components/c3_matcher/aliked_lightglue.pyAlikedLightGlueMatcher + create. Same preprocessor footprint as DISK; adds the create-time engine output-schema probe (AZ-346 AC-special-1).
  • src/gps_denied_onboard/components/c3_matcher/xfeat.pyXFeatMatcher + create. Hard-coded grayscale 384×384 preprocessor; per-candidate loop owns its own orchestration (does not call _pipeline.run_lightglue_pipeline). lightglue_runtime parameter accepted in factory signature but discarded — AC-special-1.
  • src/gps_denied_onboard/components/c3_matcher/_pipeline.py — shared per-frame orchestration used by DISK + ALIKED. Owns the drop-and-continue loop, RANSAC sort, residual warn, health-window update, and the four FDR record kinds (matcher.frame_done, matcher.backbone_error, matcher.insufficient_inliers, matcher.all_failed).
  • src/gps_denied_onboard/components/c3_matcher/inference_runtime_cut.py — consumer-side InferenceRuntimeCut Protocol over C7 (AZ-507). Includes TilePixelHandle duck-typing note.
  • src/gps_denied_onboard/components/c3_matcher/_engine_output_assertion.pyassert_keypoint_engine_output_schema helper. Single home for the AZ-346 create-time probe so future keypoint-backbone strategies reuse the same error envelope.
  • src/gps_denied_onboard/components/c3_5_adhop/adhop_refiner.pyAdHoPRefiner + create. Owns the conditional gate, the rolling 60-s invocation-rate window, the rate-limited WARN log, and the passthrough fall-through on RefinerBackboneError.
  • src/gps_denied_onboard/components/c3_5_adhop/inference_runtime_cut.py — consumer-side InferenceRuntimeCut Protocol over C7 (AZ-507).
  • tests/unit/c3_matcher/test_az345_346_347_concrete_matchers.py — 43 parametrised tests covering AC-1..AC-12 for all three strategies plus AZ-346 AC-special-1 (engine schema mismatch ×2) and AZ-347 AC-special-1 (no LightGlue call).
  • tests/unit/c3_5_adhop/test_az349_adhop_refiner.py — 23 tests covering AZ-349 AC-1..AC-11.

Modified (5)

  • src/gps_denied_onboard/components/c3_matcher/config.py — added ransac_threshold_px, disk_weights_path, aliked_weights_path, xfeat_weights_path. Each new field validated in __post_init__.
  • src/gps_denied_onboard/components/c3_5_adhop/config.py — added adhop_weights_path, ransac_threshold_px, ratelimited_warn_window_ns.
  • src/gps_denied_onboard/runtime_root/matcher_factory.py — extended build_matcher_strategy to optionally forward clock + fdr_client to the strategy's create; older strategies that don't accept them remain unbroken.
  • src/gps_denied_onboard/runtime_root/refiner_factory.py — same extension for AdHoP / passthrough.
  • src/gps_denied_onboard/fdr_client/records.py — registered four new C3 matcher record kinds (matcher.frame_done, matcher.backbone_error, matcher.insufficient_inliers, matcher.all_failed) and one C3.5 refiner kind (refiner.frame_done).
  • tests/unit/c3_5_adhop/test_protocol_conformance.py — updated the AZ-348 AC-7 "AdHoP module not yet built" stop-gap to assert the module now imports AND that the factory raises RefinerConfigError when the weights path is missing (the AZ-349 cold-fail-fast behaviour).
  • tests/unit/test_az272_fdr_record_schema.py — added round-trip fixture payloads for all five new kinds.

Task Results

Task Status Files Modified Focused tests AC Coverage Issues
AZ-345 Done 5 added / 2 modified 39/39 pass 12/12 covered None
AZ-346 Done 4 added / 2 modified 41/41 pass 14/14 covered None
AZ-347 Done 2 added / 2 modified 27/27 pass 13/13 covered (AC-special-2 informational) None
AZ-349 Done 2 added / 2 modified 23/23 pass 11/11 covered None

AC Test Coverage: 47/47 covered

(AZ-347 AC-special-2 latency benchmark is informational per spec and deferred to C3-PT-01 / E-BBT.)

Code Review Verdict: PASS_WITH_WARNINGS

See _docs/03_implementation/reviews/batch_57_review.md. Three Low findings recorded; no Critical / High / Architecture findings. Auto-fix not required.

Auto-Fix Attempts: 0

Stuck Agents: None

Next Batch

This concludes the C3 matcher + C3.5 refiner concrete-strategy track for cycle 1. The cumulative-review window (batches 5557) is now due under the K=3 cadence.