Second of six subtasks of AZ-618. Extends airborne_bootstrap.build_pre_constructed(config) additively with the two C6 storage entries on top of AZ-619's c13_fdr + clock contract: - c6_descriptor_index: via storage_factory.build_descriptor_index - c6_tile_store: via storage_factory.build_tile_store When BUILD_FAISS_INDEX=OFF, the lower-level RuntimeNotAvailableError from the descriptor index factory is translated into an AirborneBootstrapError that names the missing key (c6_descriptor_index), the gating flag (BUILD_FAISS_INDEX), and the consuming component slug(s) drawn from AIRBORNE_REQUIRED_PRE_CONSTRUCTED_KEYS. The original error is preserved as __cause__ so operators still see the upstream reason. Tests: 3 new unit tests cover AC-620.1 + AC-620.2 (twice, with and without a configured consumer, so the bootstrap fails loudly in either branch). AZ-619 tests updated to add an autouse stub for the Phase B builders (keeps them focused on Phase A keys) and to relax the "exactly two keys" assertion to "AZ-619 keys remain present under AZ-620 additivity" per the original test's own forward-pointer. Bonus: ruff --fix removed 12 pre-existing UP037 quoted-annotation warnings in airborne_bootstrap.py (covered by `from __future__ import annotations`). All in modified-area scope per quality-gates.mdc. Run: pytest tests/unit/runtime_root/ -q -> 15/15 passed in 1.06s. Spec moved to _docs/02_tasks/done/ in the previous commit (audit-trail backfill of batch_90 also landed there). Co-authored-by: Cursor <cursoragent@cursor.com>
6.3 KiB
Batch 91 Report — AZ-620 Phase B: build_pre_constructed seeds c6_descriptor_index + c6_tile_store (cycle 1)
Batch: 91 Date: 2026-05-19 Context: Product implementation (greenfield Step 7 — Implement; AZ-618 umbrella, Phase B of 6) Tasks: AZ-620 (3 cp) — 1 task Cycle: 1 Verdict: COMPLETE — PASS (self-reviewed inline; 15/15 runtime_root tests green)
Summary
Second of six subtasks decomposing the AZ-618 umbrella. Phase B extends airborne_bootstrap.build_pre_constructed(config) additively, adding the two C6 storage entries (c6_descriptor_index, c6_tile_store) on top of AZ-619's foundational c13_fdr + clock. Wraps the existing C6 factories so a BUILD_FAISS_INDEX=OFF mismatch surfaces a clear operator-facing AirborneBootstrapError instead of bubbling up the lower-level RuntimeNotAvailableError with no consuming-component context.
AZ-620 — build_pre_constructed Phase B (3 cp)
-
src/gps_denied_onboard/runtime_root/airborne_bootstrap.py:- Imports
build_descriptor_index+build_tile_storefromstorage_factory, andRuntimeNotAvailableErrorfromerrors. - New public constant
FAISS_BUILD_FLAG = "BUILD_FAISS_INDEX"(exported in__all__) — single source of truth for the flag name embedded in error messages. - New module-private helpers:
_consumers_of_pre_constructed_key(key)— readsAIRBORNE_REQUIRED_PRE_CONSTRUCTED_KEYSto find which slugs need a given key._configured_consumers_of_pre_constructed_key(config, key)— narrows to consumers present inconfig.components; falls back to the full theoretical set when no components are configured (so error messages stay informative under bareConfig())._build_c6_descriptor_index(config)— callsbuild_descriptor_index; onRuntimeNotAvailableError, re-raises asAirborneBootstrapErrornamingc6_descriptor_index,BUILD_FAISS_INDEX, and the consuming component slug(s). Preserves the original error viaraise ... from exc._build_c6_tile_store(config)— thin pass-through tobuild_tile_store(noBUILD_*flag gates this side).
build_pre_constructed(config)now returns four keys:c13_fdr,clock,c6_descriptor_index,c6_tile_store. Additivity preserved per AZ-620 Constraint "MUST be additive on top of AZ-619".- Bonus hygiene (mechanical):
ruff --fixremoved 12 pre-existing UP037 quoted-annotation warnings in the same file (covered byfrom __future__ import annotationsat line 49). All 12 lints were in the modified-area scope per.cursor/rules/quality-gates.mdc.
- Imports
-
tests/unit/runtime_root/test_az619_pre_constructed_phase_a.py:- New autouse fixture
_stub_c6_buildersmonkeypatches_build_c6_descriptor_index+_build_c6_tile_storeto opaque sentinels — keeps AZ-619 tests focused on Phase A keys without entangling them with the new Phase B integration paths (and avoids requiring real Postgres + FAISS for the AZ-619 cases). test_phase_a_only_seeds_two_keysrenamed totest_phase_a_keys_remain_present_under_az620_additivity: now asserts AZ-619 keys are a SUBSET of the returned dict (not exact equality), matching the explicit forward-pointer that the original docstring carried ("this test will be relaxed at that point").
- New autouse fixture
-
tests/unit/runtime_root/test_az620_pre_constructed_phase_b.py(new):test_ac_620_1_adds_c6_descriptor_index_and_c6_tile_store— stubs both C6 factories to identifiable mocks; asserts the bootstrap dict contains both Phase B keys referencing the patched returns, and AZ-619 keys are still present. Covers AC-620.1.test_ac_620_2_build_flag_off_with_configured_c2_vpr_raises_named_error— stubsbuild_descriptor_indexto raiseRuntimeNotAvailableError(mirroring realBUILD_FAISS_INDEX=OFFbehaviour); builds a config withc2_vpr.strategy="net_vlad"; assertsAirborneBootstrapErroris raised with all three names (c6_descriptor_index,BUILD_FAISS_INDEX,c2_vpr) and the original error preserved as__cause__. Covers AC-620.2.test_ac_620_2_no_configured_consumer_still_raises_with_full_set— defence-in-depth: even with no consumer configured, the bootstrap still fails loudly (rather than silently dropping the key); the message lists the full theoretical consumer set. Strengthens AC-620.2's operator-facing contract.
File Ownership
- OWNED (component
runtime_root):src/gps_denied_onboard/runtime_root/airborne_bootstrap.pytests/unit/runtime_root/test_az619_pre_constructed_phase_a.pytests/unit/runtime_root/test_az620_pre_constructed_phase_b.py
- READ-ONLY: imports from
runtime_root.storage_factory(same package),runtime_root.errors,clock,fdr_client,config,c6_tile_cache.interface(TYPE_CHECKING via storage_factory only). - No FORBIDDEN-zone writes.
Test Results
- New unit tests: 3 under
tests/unit/runtime_root/test_az620_pre_constructed_phase_b.pycovering AC-620.1 + AC-620.2 (twice, defence-in-depth). - Updated unit tests: 5 AZ-619 tests still passing after autouse-stub fixture and relaxed-equality assertion.
- AZ-591 regression (
test_az591_airborne_bootstrap.py): 7/7 passing —AIRBORNE_REQUIRED_PRE_CONSTRUCTED_KEYStable consistency + airborne registration semantics + tier isolation all unchanged. - Combined:
pytest tests/unit/runtime_root/ -q→ 15/15 passed in 1.06 s. - No new ruff errors on touched files; 12 pre-existing UP037 warnings in the same file fixed.
Out of scope (deferred)
- All other keys in
AIRBORNE_REQUIRED_PRE_CONSTRUCTED_KEYS— AZ-621 (c7 inference), AZ-622 (c3 runtimes), AZ-623 (RANSAC + c5 helpers), AZ-624 (main()integration + AC-1..AC-5). - Real Postgres + FAISS integration testing — covered by the existing AZ-303 / AZ-305 / AZ-306 component-level tests; not duplicated at the bootstrap layer.
- Mandatory-Tier-2 Jetson run — consolidated at AZ-624.
State
- Spec moved:
_docs/02_tasks/todo/AZ-620_pre_constructed_phase_b_c6_storage.md→_docs/02_tasks/done/. - Tracker: AZ-620 transitioned To Do → In Progress at batch start; will transition In Progress → In Testing after this commit (per implement skill Step 12).
_docs/_autodev_state.mdadvanced tolast_completed_batch: 91.
Next Batch
- Batch 92: AZ-621 (3 cp) — Phase C of AZ-618 umbrella. Adds
c7_inferenceengine tobuild_pre_constructed. Depends on AZ-619 + AZ-620 (both will be indone/after this commit).