# Jira Epics — Semantic Detection System

> Epics created in Jira project AZ (AZAION) on 2026-03-20.

## Epic → Jira ID Mapping

| # | Epic | Jira ID |
|---|------|---------|
| 1 | Bootstrap & Initial Structure | AZ-130 |
| 2 | Tier1Detector — YOLOE TensorRT Inference | AZ-131 |
| 3 | Tier2SpatialAnalyzer — Spatial Pattern Analysis | AZ-132 |
| 4 | VLMClient — NanoLLM IPC Client | AZ-133 |
| 5 | GimbalDriver — ViewLink Serial Control | AZ-134 |
| 6 | OutputManager — Recording & Logging | AZ-135 |
| 7 | ScanController — Behavior Tree Orchestrator | AZ-136 |
| 8 | Integration Tests — End-to-End System Testing | AZ-137 |

## Dependency Order

```
1. AZ-130 Bootstrap & Initial Structure  (no dependencies)
2. AZ-131 Tier1Detector                  (depends on AZ-130)
3. AZ-132 Tier2SpatialAnalyzer           (depends on AZ-130)  ← parallel with 2,4,5,6
4. AZ-133 VLMClient                      (depends on AZ-130)  ← parallel with 2,3,5,6
5. AZ-134 GimbalDriver                   (depends on AZ-130)  ← parallel with 2,3,4,6
6. AZ-135 OutputManager                  (depends on AZ-130)  ← parallel with 2,3,4,5
7. AZ-136 ScanController                 (depends on AZ-130–AZ-135)
8. AZ-137 Integration Tests              (depends on AZ-136)
```

---

## Epic 1: Bootstrap & Initial Structure

**Summary**: Scaffold the project: folder structure, shared models, interfaces, stubs, CI/CD config, Docker setup, test infrastructure.

**Problem / Context**: The semantic detection module needs a clean project scaffold that integrates with the existing Cython + TensorRT codebase. All components share Config and Types helpers that must exist before any implementation.

**Scope**:

In Scope:
- Project folder structure matching architecture
- Config helper: YAML loading, validation, typed access, dev/prod configs
- Types helper: all shared dataclasses (FrameContext, Detection, POI, GimbalState, CapabilityFlags, SpatialAnalysisResult, Waypoint, VLMResponse, SearchScenario)
- Interface stubs for all 6 components
- Docker setup: dev Dockerfile, docker-compose with mock services
- CI pipeline config: lint, test, build stages
- Test infrastructure: pytest setup, fixture directory, mock factories

Out of Scope:
- Component implementation (handled in component epics)
- Real hardware integration
- Model training / export

**Dependencies**:
- Epic dependencies: None (first epic)
- External: Existing detections repository access

**Effort Estimation**: M / 5-8 points

**Acceptance Criteria**:

| # | Criterion | Measurable Condition |
|---|-----------|---------------------|
| 1 | Config helper loads and validates YAML | Unit tests pass for valid/invalid configs |
| 2 | Types helper defines all shared structs | All dataclasses importable, fields match spec |
| 3 | Docker dev environment boots | `docker compose up` succeeds, health endpoint returns |
| 4 | CI pipeline runs lint + test | Pipeline passes on scaffold code |

**Risks**:

| # | Risk | Mitigation |
|---|------|------------|
| 1 | Cython build system integration | Start with pure Python, Cython-ize later |
| 2 | Config schema changes during development | Version field in config, validation tolerant of additions |

**Labels**: `component:bootstrap`, `type:platform`

**Child Issues**:

| Type | Title | Points |
|------|-------|--------|
| Task | Create project folder structure and pyproject.toml | 1 |
| Task | Implement Config helper with YAML validation | 3 |
| Task | Implement Types helper with all shared dataclasses | 2 |
| Task | Create interface stubs for all 6 components | 2 |
| Task | Docker dev setup + docker-compose | 3 |
| Task | CI pipeline config (lint, test, build) | 2 |
| Task | Test infrastructure (pytest, fixtures, mock factories) | 2 |

---

## Epic 2: Tier1Detector — YOLOE TensorRT Inference

**Summary**: Wrap YOLOE TensorRT FP16 inference for detection + segmentation on aerial frames.

**Problem / Context**: The system needs fast (<100ms) object detection including segmentation masks for footpaths and concealment indicators. Must support both YOLOE-11 and YOLOE-26 backbones.

**Scope**:

In Scope:
- TRT engine loading with class name configuration
- Frame preprocessing (resize, normalize)
- Detection + segmentation inference
- NMS handling for YOLOE-11 (NMS-free for YOLOE-26)
- ONNX Runtime fallback for dev environment

Out of Scope:
- Model training and export (separate repo)
- Custom class fine-tuning

**Dependencies**:
- Epic dependencies: Bootstrap
- External: Pre-exported TRT engine files, Ultralytics 8.4.x

**Effort Estimation**: M / 5-8 points

**Acceptance Criteria**:

| # | Criterion | Measurable Condition |
|---|-----------|---------------------|
| 1 | Inference ≤100ms on Jetson Orin Nano Super | PT-01 passes |
| 2 | New classes P≥80%, R≥80% on validation set | AT-01 passes |
| 3 | Existing classes not degraded | AT-02 passes (mAP50 within 2% of baseline) |
| 4 | GPU memory ≤2.5GB | PT-03 passes |

**Risks**:

| # | Risk | Mitigation |
|---|------|------------|
| 1 | R01: Backbone accuracy on concealment data | Benchmark sprint; dual backbone strategy |
| 2 | YOLOE-26 NMS-free model packaging | Validate engine metadata detection at load time |

**Labels**: `component:tier1-detector`, `type:inference`

**Child Issues**:

| Type | Title | Points |
|------|-------|--------|
| Spike | Benchmark YOLOE-11 vs YOLOE-26 on 200 annotated frames | 3 |
| Task | Implement TRT engine loader with class name config | 3 |
| Task | Implement detect() with preprocessing + postprocessing | 3 |
| Task | Add ONNX Runtime fallback for dev environment | 2 |
| Task | Write unit + integration tests for Tier1Detector | 2 |

---

## Epic 3: Tier2SpatialAnalyzer — Spatial Pattern Analysis

**Summary**: Analyze spatial patterns from Tier 1 detections — trace footpath masks and cluster discrete objects — producing waypoints for gimbal navigation.

**Problem / Context**: After Tier 1 detects objects, spatial reasoning is needed to trace footpaths to endpoints (concealed positions) and group clustered objects (defense networks). This is the core semantic reasoning layer.

**Scope**:

In Scope:
- Mask tracing: skeletonize → prune → endpoints → classify
- Cluster tracing: spatial clustering → visit order → per-point classify
- ROI classification heuristic (darkness + contrast)
- Freshness tagging for mask traces

Out of Scope:
- CNN classifier (removed from V1)
- Machine learning-based classification (V2+)

**Dependencies**:
- Epic dependencies: Bootstrap
- External: scikit-image, scipy

**Effort Estimation**: M / 5-8 points

**Acceptance Criteria**:

| # | Criterion | Measurable Condition |
|---|-----------|---------------------|
| 1 | trace_mask ≤200ms on 1080p mask | PT-01 passes |
| 2 | Concealed position recall ≥60% | AT-01 passes |
| 3 | Footpath endpoint detection ≥70% | AT-02 passes |
| 4 | Freshness tags correctly assigned | AT-03 passes (≥80% high-contrast correct) |

**Risks**:

| # | Risk | Mitigation |
|---|------|------------|
| 1 | R03: High false positive rate from heuristic | Conservative thresholds; per-season config |
| 2 | R07: Fragmented masks | Morphological closing; min-branch pruning |

**Labels**: `component:tier2-spatial-analyzer`, `type:inference`

**Child Issues**:

| Type | Title | Points |
|------|-------|--------|
| Task | Implement mask tracing pipeline (skeletonize, prune, endpoints) | 5 |
| Task | Implement cluster tracing (spatial clustering, visit order) | 3 |
| Task | Implement analyze_roi heuristic (darkness + contrast + freshness) | 3 |
| Task | Write unit + integration tests for Tier2SpatialAnalyzer | 2 |

---

## Epic 4: VLMClient — NanoLLM IPC Client

**Summary**: IPC client for communicating with the NanoLLM Docker container via Unix domain socket for Tier 3 visual language model analysis.

**Problem / Context**: Ambiguous Tier 2 results need deep visual analysis via VILA1.5-3B VLM. The VLM runs in a separate Docker container; this client manages the IPC protocol and model lifecycle (load/unload for GPU memory management).

**Scope**:

In Scope:
- Unix domain socket client (connect, disconnect)
- JSON IPC protocol (analyze, load_model, unload_model, status)
- Model lifecycle management (load on demand, unload to free GPU)
- Timeout handling, retry logic, availability tracking

Out of Scope:
- VLM model selection/training
- NanoLLM Docker container itself (pre-built)

**Dependencies**:
- Epic dependencies: Bootstrap
- External: NanoLLM Docker container with VILA1.5-3B

**Effort Estimation**: S / 3-5 points

**Acceptance Criteria**:

| # | Criterion | Measurable Condition |
|---|-----------|---------------------|
| 1 | Round-trip analyze ≤5s | PT-01 passes |
| 2 | GPU memory released on unload | PT-02 passes (≤baseline+50MB) |
| 3 | 3 consecutive failures → unavailable | IT-06 passes |
| 4 | Temp files cleaned after analyze | ST-02 passes |

**Risks**:

| # | Risk | Mitigation |
|---|------|------------|
| 1 | R02: VLM load latency (5-10s) | Predictive loading when first POI queued |
| 2 | R04: GPU memory pressure | Sequential scheduling; explicit unload |

**Labels**: `component:vlm-client`, `type:integration`

**Child Issues**:

| Type | Title | Points |
|------|-------|--------|
| Task | Implement Unix socket client (connect, disconnect, protocol) | 3 |
| Task | Implement model lifecycle management (load, unload, status) | 2 |
| Task | Implement analyze() with timeout, retry, availability tracking | 3 |
| Task | Write unit + integration tests for VLMClient | 2 |

---

## Epic 5: GimbalDriver — ViewLink Serial Control

**Summary**: Hardware adapter for the ViewPro A40 gimbal, implementing the ViewLink serial protocol for pan/tilt/zoom control and PID-based path following.

**Problem / Context**: The scan controller needs to point the camera at specific angles and follow paths. This requires implementing the ViewLink Serial Protocol V3.3.3 over UART, plus a PID controller for smooth path tracking. A mock TCP mode enables development without hardware.

**Scope**:

In Scope:
- ViewLink protocol: send commands, receive state, checksum validation
- Pan/tilt/zoom absolute control
- PID dual-axis path following
- Mock TCP mode for development
- Retry logic with CRC validation

Out of Scope:
- Advanced gimbal features (tracking modes, stabilization tuning)
- Hardware EMI mitigation (physical, not software)

**Dependencies**:
- Epic dependencies: Bootstrap
- External: ViewLink Protocol V3.3.3 specification, pyserial

**Effort Estimation**: L / 8-13 points

**Acceptance Criteria**:

| # | Criterion | Measurable Condition |
|---|-----------|---------------------|
| 1 | Command latency ≤500ms | PT-01 passes |
| 2 | Zoom transition ≤2s | PT-02, AT-02 pass |
| 3 | PID keeps path in center 50% | AT-03 passes (≥90% of cycles) |
| 4 | Smooth transitions (jerk ≤50 deg/s³) | PT-03 passes |

**Risks**:

| # | Risk | Mitigation |
|---|------|------------|
| 1 | R08: ViewLink protocol implementation effort | ArduPilot C++ reference; mock mode for parallel dev |
| 2 | PID tuning on real hardware | Configurable gains; bench test phase |

**Labels**: `component:gimbal-driver`, `type:hardware`

**Child Issues**:

| Type | Title | Points |
|------|-------|--------|
| Spike | Parse ViewLink V3.3.3 protocol spec, document packet format | 3 |
| Task | Implement UART/TCP connection layer with mock mode | 3 |
| Task | Implement command send/receive with checksum and retry | 5 |
| Task | Implement PID dual-axis controller with anti-windup | 3 |
| Task | Implement zoom_to_poi, return_to_sweep, follow_path | 3 |
| Task | Write unit + integration tests for GimbalDriver | 2 |
| Task | Mock gimbal TCP server for dev/test | 2 |

---

## Epic 6: OutputManager — Recording & Logging

**Summary**: Facade over all persistent output: detection logging, frame recording, health logging, gimbal logging, and operator detection delivery.

**Problem / Context**: Every flight produces data needed for operator situational awareness, post-flight review, and training data collection. Recording must never block inference. NVMe storage requires circular buffer management.

**Scope**:

In Scope:
- Detection JSON-lines logger (append, flush)
- JPEG frame recorder (L1 at 2 FPS, L2 at 30 FPS)
- Health and gimbal command logging
- Operator delivery in YOLO-compatible format
- NVMe storage monitoring and circular buffer

Out of Scope:
- Data export/upload tools
- Long-term storage management

**Dependencies**:
- Epic dependencies: Bootstrap
- External: NVMe SSD, OpenCV for JPEG encoding

**Effort Estimation**: S / 3-5 points

**Acceptance Criteria**:

| # | Criterion | Measurable Condition |
|---|-----------|---------------------|
| 1 | 30 FPS frame recording without dropped frames | PT-01 passes |
| 2 | No memory leak under sustained load | PT-02 passes (≤10MB growth) |
| 3 | Storage warning triggers at <20% free | IT-07 passes |
| 4 | Write failures don't block caller | IT-09 passes |

**Risks**:

| # | Risk | Mitigation |
|---|------|------------|
| 1 | R11: NVMe write latency at 30 FPS | Async writes; drop frames if queue backs up |
| 2 | R09: Operator overload | Confidence thresholds; detection throttle |

**Labels**: `component:output-manager`, `type:data`

**Child Issues**:

| Type | Title | Points |
|------|-------|--------|
| Task | Implement detection JSON-lines logger | 2 |
| Task | Implement JPEG frame recorder with rate control | 3 |
| Task | Implement health + gimbal command logging | 1 |
| Task | Implement operator delivery in YOLO format | 2 |
| Task | Implement NVMe storage monitor + circular buffer | 3 |
| Task | Write unit + integration tests for OutputManager | 2 |

---

## Epic 7: ScanController — Behavior Tree Orchestrator

**Summary**: Central orchestrator implementing the two-level scan strategy via a py_trees behavior tree with data-driven search scenarios.

**Problem / Context**: All components need coordination: L1 sweep finds POIs, L2 investigation analyzes them via the appropriate subtree (path_follow, cluster_follow, area_sweep, zoom_classify), and results flow to the operator. Health monitoring provides graceful degradation.

**Scope**:

In Scope:
- Behavior tree structure (Root, HealthGuard, L2Investigation, L1Sweep, Idle)
- All 4 investigation subtrees (PathFollow, ClusterFollow, AreaSweep, ZoomClassify)
- POI queue with priority management and deduplication
- EvaluatePOI with scenario-aware trigger matching
- Search scenario YAML loading and dispatching
- Health API endpoint (/api/v1/health)
- Capability flags and graceful degradation

Out of Scope:
- Component internals (delegated to respective components)
- New investigation types (extensible via BT subtrees)

**Dependencies**:
- Epic dependencies: Bootstrap, Tier1Detector, Tier2SpatialAnalyzer, VLMClient, GimbalDriver, OutputManager
- External: py_trees 2.4.0, FastAPI

**Effort Estimation**: L / 8-13 points

**Acceptance Criteria**:

| # | Criterion | Measurable Condition |
|---|-----------|---------------------|
| 1 | L1→L2 transition ≤2s | PT-01 passes |
| 2 | Full L1→L2→L1 cycle works | AT-03 passes |
| 3 | POI queue orders by priority | IT-09 passes |
| 4 | HealthGuard degrades gracefully | IT-11 passes |
| 5 | Coexists with YOLO (≤5% FPS reduction) | PT-02 passes |

**Risks**:

| # | Risk | Mitigation |
|---|------|------------|
| 1 | R06: Config complexity → runtime errors | Validation at startup; skip invalid scenarios |
| 2 | Single-threaded BT bottleneck | Leaf nodes delegate to optimized C/TRT backends |

**Labels**: `component:scan-controller`, `type:orchestration`

**Child Issues**:

| Type | Title | Points |
|------|-------|--------|
| Task | Implement BT skeleton: Root, HealthGuard, L1Sweep, L2Investigation, Idle | 5 |
| Task | Implement EvaluatePOI with scenario-aware matching + cluster aggregation | 3 |
| Task | Implement PathFollowSubtree (TraceMask, PIDFollow, WaypointAnalysis) | 5 |
| Task | Implement ClusterFollowSubtree (TraceCluster, VisitLoop, ClassifyWaypoint) | 3 |
| Task | Implement AreaSweepSubtree and ZoomClassifySubtree | 3 |
| Task | Implement POI queue (priority, deduplication, max size) | 2 |
| Task | Implement health API endpoint + capability flags | 2 |
| Task | Write unit + integration tests for ScanController | 3 |

---

## Epic 8: Integration Tests — End-to-End System Testing

**Summary**: Implement the black-box integration test suite defined in `_docs/02_plans/integration_tests/`.

**Problem / Context**: The system must be validated end-to-end using Docker-based tests that treat the semantic detection module as a black box, verifying all acceptance criteria and cross-component interactions.

**Scope**:

In Scope:
- Functional integration tests (all scenarios from integration_tests/functional_tests.md)
- Non-functional tests (performance, resilience)
- Docker test environment setup
- Test data management
- CI integration

Out of Scope:
- Unit tests (covered in component epics)
- Field testing on real hardware

**Dependencies**:
- Epic dependencies: ScanController (all components integrated)
- External: Docker, test data set

**Effort Estimation**: M / 5-8 points

**Acceptance Criteria**:

| # | Criterion | Measurable Condition |
|---|-----------|---------------------|
| 1 | All functional test scenarios pass | Green CI for functional suite |
| 2 | ≥76% AC coverage in traceability matrix | Coverage report |
| 3 | Docker test env boots with `docker compose up` | Setup documented and reproducible |

**Risks**:

| # | Risk | Mitigation |
|---|------|------------|
| 1 | Test data availability (annotated imagery) | Use synthetic data for CI; real data for acceptance |
| 2 | Mock services diverge from real behavior | Keep mocks minimal; integration tests catch drift |

**Labels**: `component:integration-tests`, `type:testing`

**Child Issues**:

| Type | Title | Points |
|------|-------|--------|
| Task | Docker test environment + compose setup | 3 |
| Task | Implement functional integration tests (positive scenarios) | 5 |
| Task | Implement functional integration tests (negative/edge scenarios) | 3 |
| Task | Implement non-functional tests (performance, resilience) | 3 |
| Task | CI integration and test reporting | 2 |

---

## Summary

| # | Jira ID | Epic | T-shirt | Points Range | Dependencies |
|---|---------|------|---------|-------------|-------------|
| 1 | AZ-130 | Bootstrap & Initial Structure | M | 5-8 | None |
| 2 | AZ-131 | Tier1Detector | M | 5-8 | AZ-130 |
| 3 | AZ-132 | Tier2SpatialAnalyzer | M | 5-8 | AZ-130 |
| 4 | AZ-133 | VLMClient | S | 3-5 | AZ-130 |
| 5 | AZ-134 | GimbalDriver | L | 8-13 | AZ-130 |
| 6 | AZ-135 | OutputManager | S | 3-5 | AZ-130 |
| 7 | AZ-136 | ScanController | L | 8-13 | AZ-130–AZ-135 |
| 8 | AZ-137 | Integration Tests | M | 5-8 | AZ-136 |
| **Total** | | | | **42-68** | |
