[AZ-355] C4 PoseEstimator Protocol + factory + DTOs + composition

Land the foundational C4 surface AZ-358 (Marginals) and AZ-361
(Hybrid) build on top of:

- PoseEstimator Protocol (@runtime_checkable): estimate(...) +
  current_covariance_mode().
- Error hierarchy: PoseEstimatorError, PnpFailureError,
  PoseEstimatorConfigError; CovarianceDegradedWarning as a Warning
  subclass (warnings.warn path, not raised).
- ISam2GraphHandle Protocol stub (READ-ONLY view, get_pose_key only)
  decoupled from C5's concrete ISam2GraphHandleImpl.
- C4PoseConfig (frozen dataclass) + register on c4_pose import.
- runtime_root/pose_factory.build_pose_estimator with lazy-import
  fallback; INFO log c4.pose.strategy_loaded; shares ingest-thread
  binding with C5 per ADR-003.

DTO restructuring (cross-cutting): retire the legacy raw-4x4
PoseEstimate(int frame_id, datetime timestamp, pose_se3, ...) and
ship the contract shape PoseEstimate(UUID, LatLonAlt, Quat,
np.ndarray, CovarianceMode, PoseSourceLabel,
last_satellite_anchor_age_ms, emitted_at). C5 add_pose_anchor in
both gtsam_isam2 + eskf_baseline migrated in lockstep via
WGS84->ENU + Quat->R helpers; test fixtures updated. VIO output
stays on the raw shape until AZ-331 (C1 protocol) lands.

LatLonAlt upgraded to slots=True per AC-2. ThermalState stub added
to _types/thermal.py so the Protocol typechecks pre-AZ-302.

Tests: 25 new in tests/unit/c4_pose/test_az355_pose_protocol.py
covering AC-1..AC-10 + factory wiring + config validation; full
repo: 685 passed, 2 pre-existing CI-only skips.

Jira transition deferred: MCP "Not connected"; leftover entry in
_docs/_process_leftovers/2026-05-11_jira_transition_az355_deferred.md.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-05-11 10:32:14 +03:00
parent c0bdb57957
commit db27e25630
19 changed files with 1407 additions and 52 deletions
@@ -0,0 +1,45 @@
# Jira transition for AZ-355 deferred — MCP "Not connected"
**Recorded**: 2026-05-11T10:50+03:00 (Europe/Kyiv)
**Status**: deferred-non-user (replay on next autodev invocation when Jira MCP is connected)
## What is blocked
Status transition of `AZ-355` from `To Do``Done` to reflect that
Batch 20 has landed the C4 `PoseEstimator` Protocol + factory + DTOs
+ composition wiring (see
`_docs/03_implementation/batch_20_cycle1_report.md`).
## Why
The Atlassian MCP server returned `"Not connected"` on
`getAccessibleAtlassianResources` during the Batch 20 wrap-up — same
failure mode that AZ-386 hit a few hours earlier. Per the
Leftovers Mechanism the write is recorded here and the non-tracker
work (commit, push) is allowed to proceed; the next autodev
invocation will replay the transition.
## Replay payload
- **Tool**: `transitionJiraIssue`
- **cloudId**: `denyspopov.atlassian.net`
- **issueIdOrKey**: `AZ-355`
- **target status**: `Done` (transition id is project-specific; resolve
via `getTransitionsForJiraIssue` at replay time — Jira project `AZ`
uses the standard "Software" workflow so the transition is `id: 31`
in current Jira config; confirm at replay time).
## Acceptance check on replay
After the transition succeeds:
- `getJiraIssue(AZ-355)` returns `fields.status.name == "Done"`.
- Delete this leftover file.
## Notes
- Code, tests, docs, and state file are all updated and committed. The
only outstanding action is the tracker status transition; the
AZ-355 task spec is already in `_docs/02_tasks/done/`.
- The previous leftover for AZ-386 is still pending; replay both in
one batch when the MCP comes back.