diff --git a/_docs/02_tasks/_dependencies_table.md b/_docs/02_tasks/_dependencies_table.md index 7d05446..11cd88c 100644 --- a/_docs/02_tasks/_dependencies_table.md +++ b/_docs/02_tasks/_dependencies_table.md @@ -1,56 +1,44 @@ # Dependencies Table -**Date**: 2026-03-22 -**Total Tasks**: 11 -**Total Complexity Points**: 35 +**Date**: 2026-03-31 +**Total Tasks**: 15 (11 done + 4 new) +**Total Complexity Points**: 43 -| Task | Name | Complexity | Dependencies | Epic | -|------|------|-----------|-------------|------| -| AZ-138 | test_infrastructure | 5 | None | AZ-137 | -| AZ-139 | test_health_engine | 3 | AZ-138 | AZ-137 | -| AZ-140 | test_single_image | 3 | AZ-138 | AZ-137 | -| AZ-141 | test_tiling | 3 | AZ-138 | AZ-137 | -| AZ-142 | test_async_sse | 3 | AZ-138 | AZ-137 | -| AZ-143 | test_video | 3 | AZ-138, AZ-142 | AZ-137 | -| AZ-144 | test_negative | 2 | AZ-138 | AZ-137 | -| AZ-145 | test_resilience | 5 | AZ-138, AZ-142 | AZ-137 | -| AZ-146 | test_performance | 3 | AZ-138 | AZ-137 | -| AZ-147 | test_security | 2 | AZ-138 | AZ-137 | -| AZ-148 | test_resource_limits | 3 | AZ-138, AZ-142 | AZ-137 | +## Completed Tasks (Steps 4-6) -## Test Scenario Coverage +| Task | Name | Complexity | Dependencies | Epic | Status | +|------|------|-----------|-------------|------|--------| +| AZ-138 | test_infrastructure | 5 | None | AZ-137 | done | +| AZ-139 | test_health_engine | 3 | AZ-138 | AZ-137 | done | +| AZ-140 | test_single_image | 3 | AZ-138 | AZ-137 | done | +| AZ-141 | test_tiling | 3 | AZ-138 | AZ-137 | done | +| AZ-142 | test_async_sse | 3 | AZ-138 | AZ-137 | done | +| AZ-143 | test_video | 3 | AZ-138, AZ-142 | AZ-137 | done | +| AZ-144 | test_negative | 2 | AZ-138 | AZ-137 | done | +| AZ-145 | test_resilience | 5 | AZ-138, AZ-142 | AZ-137 | done | +| AZ-146 | test_performance | 3 | AZ-138 | AZ-137 | done | +| AZ-147 | test_security | 2 | AZ-138 | AZ-137 | done | +| AZ-148 | test_resource_limits | 3 | AZ-138, AZ-142 | AZ-137 | done | -| Task | Scenarios | -|------|-----------| -| AZ-138 | Infrastructure scaffold (no test scenarios) | -| AZ-139 | FT-P-01, FT-P-02, FT-P-14, FT-P-15 | -| AZ-140 | FT-P-03, FT-P-05, FT-P-06, FT-P-07, FT-P-13 | -| AZ-141 | FT-P-04, FT-P-16 | -| AZ-142 | FT-P-08, FT-P-09, FT-N-04 | -| AZ-143 | FT-P-10, FT-P-11, FT-P-12 | -| AZ-144 | FT-N-01, FT-N-02, FT-N-03, FT-N-05 | -| AZ-145 | FT-N-06, FT-N-07, NFT-RES-01, NFT-RES-02, NFT-RES-03, NFT-RES-04 | -| AZ-146 | NFT-PERF-01, NFT-PERF-02, NFT-PERF-03, NFT-PERF-04 | -| AZ-147 | NFT-SEC-01, NFT-SEC-02, NFT-SEC-03 | -| AZ-148 | FT-N-08, NFT-RES-LIM-01, NFT-RES-LIM-02, NFT-RES-LIM-03, NFT-RES-LIM-04 | +## New Tasks (Step 8 — Distributed Architecture) -**Total scenarios**: 39/39 covered +| Task | Name | Complexity | Dependencies | Epic | Status | +|------|------|-----------|-------------|------|--------| +| AZ-173 | stream_based_run_detect | 3 | None | AZ-172 | todo | +| AZ-174 | db_driven_ai_config | 2 | None | AZ-172 | todo | +| AZ-175 | media_table_integration | 2 | AZ-173 | AZ-172 | todo | +| AZ-176 | cleanup_obsolete_path_code | 1 | AZ-173, AZ-174 | AZ-172 | todo | -## Execution Order +## Execution Order (New Tasks) -**Batch 1** (no dependencies beyond infrastructure): -- AZ-138: test_infrastructure (5 pts) +**Batch 1** (no internal dependencies): +- AZ-173: stream_based_run_detect (3 pts) — PyAV byte-stream decoding +- AZ-174: db_driven_ai_config (2 pts) — fetch config from annotations service -**Batch 2** (depends on AZ-138 only): -- AZ-139: test_health_engine (3 pts) -- AZ-140: test_single_image (3 pts) -- AZ-141: test_tiling (3 pts) -- AZ-142: test_async_sse (3 pts) -- AZ-144: test_negative (2 pts) -- AZ-146: test_performance (3 pts) -- AZ-147: test_security (2 pts) +**Batch 2** (depends on AZ-173): +- AZ-175: media_table_integration (2 pts) — Media record lifecycle -**Batch 3** (depends on AZ-138 + AZ-142): -- AZ-143: test_video (3 pts) -- AZ-145: test_resilience (5 pts) -- AZ-148: test_resource_limits (3 pts) +**Batch 3** (depends on AZ-173 + AZ-174): +- AZ-176: cleanup_obsolete_path_code (1 pt) — remove old path-based code + +**New tasks total**: 4 tasks, 8 complexity points, 3 batches diff --git a/_docs/02_tasks/backlog/AZ-173_stream_based_run_detect.md b/_docs/02_tasks/todo/AZ-173_stream_based_run_detect.md similarity index 71% rename from _docs/02_tasks/backlog/AZ-173_stream_based_run_detect.md rename to _docs/02_tasks/todo/AZ-173_stream_based_run_detect.md index 6c15155..30a9d3b 100644 --- a/_docs/02_tasks/backlog/AZ-173_stream_based_run_detect.md +++ b/_docs/02_tasks/todo/AZ-173_stream_based_run_detect.md @@ -38,16 +38,19 @@ Remove: - `paths` iteration loop in `run_detect` - Direct `cv2.VideoCapture(local_path)` and `cv2.imread(local_path)` calls -## Video Stream Processing Options +## Video Stream Processing — PyAV (preferred) -**Option A: Write-then-read** -Write entire upload to temp file, then open with `cv2.VideoCapture`. Simple but not real-time. +Use **PyAV** (`av` package) for byte-stream video decoding. Preferred approach per user decision. -**Option B: Concurrent pipe** -One thread writes incoming bytes to a file; another thread reads frames via `cv2.VideoCapture` on the growing file. Requires careful synchronization. +**Why PyAV**: Decode frames directly from bytes/stream via `av.open(io.BytesIO(data))` without intermediate file I/O. Most flexible for streaming, no concurrent file read/write synchronization needed. -**Option C: PyAV byte-stream decoding** -Use `av.open(io.BytesIO(data))` or a custom `av.InputContainer` to decode frames directly from bytes without file I/O. Most flexible for streaming. +**Investigation needed during implementation**: +- Verify PyAV can decode frames from a growing `BytesIO` or chunked stream (not just complete files) +- Check if `av.open()` supports reading from an async generator or pipe for true streaming +- Evaluate whether simultaneous disk write can be done with a `tee`-style approach (write bytes to file while feeding to PyAV) +- Confirm PyAV frame format (RGB/BGR/YUV) compatibility with existing `process_frames` pipeline (expects BGR numpy arrays) +- Check PyAV version compatibility with the project's Python/Cython setup +- Fallback: if PyAV streaming is not viable, use write-then-read with `cv2.VideoCapture` on completed file ## Acceptance Criteria diff --git a/_docs/02_tasks/backlog/AZ-174_db_driven_ai_config.md b/_docs/02_tasks/todo/AZ-174_db_driven_ai_config.md similarity index 100% rename from _docs/02_tasks/backlog/AZ-174_db_driven_ai_config.md rename to _docs/02_tasks/todo/AZ-174_db_driven_ai_config.md diff --git a/_docs/02_tasks/backlog/AZ-175_media_table_integration.md b/_docs/02_tasks/todo/AZ-175_media_table_integration.md similarity index 100% rename from _docs/02_tasks/backlog/AZ-175_media_table_integration.md rename to _docs/02_tasks/todo/AZ-175_media_table_integration.md diff --git a/_docs/02_tasks/backlog/AZ-176_cleanup_obsolete_path_code.md b/_docs/02_tasks/todo/AZ-176_cleanup_obsolete_path_code.md similarity index 100% rename from _docs/02_tasks/backlog/AZ-176_cleanup_obsolete_path_code.md rename to _docs/02_tasks/todo/AZ-176_cleanup_obsolete_path_code.md diff --git a/_docs/_autopilot_state.md b/_docs/_autopilot_state.md index 4ec616d..d3cb6c4 100644 --- a/_docs/_autopilot_state.md +++ b/_docs/_autopilot_state.md @@ -2,53 +2,8 @@ ## Current Step flow: existing-code -step: 7 -name: Refactor -status: completed -sub_step: done +step: 9 +name: Implement +status: not_started +sub_step: 0 retry_count: 0 - -## Completed Steps - -| Step | Name | Completed | Key Outcome | -|------|------|-----------|-------------| -| 1 | Document | 2026-03-21 | 10 modules, 4 components, full _docs/ generated from existing codebase | -| 2 | Test Spec | 2026-03-21 | 39 test scenarios (16 positive, 8 negative, 11 non-functional), 85% total coverage, 5 artifacts produced | -| 3 | Code Testability Rev. | 2026-03-29 | Engine factory refactoring completed: polymorphic EngineClass pattern (TensorRT/CoreML/ONNX) with auto-detection. Hardcoded values aligned with Docker compose. | -| 4 | Decompose Tests | 2026-03-23 | 11 tasks (AZ-138..AZ-148), 35 complexity points, 3 batches. Phase 3 test data gate PASSED: 39/39 scenarios validated, 12 data files provided. | -| 5 | Implement Tests | 2026-03-23 | 11 tasks implemented across 4 batches, 38 tests (2 skipped), all code reviews PASS_WITH_WARNINGS. Commits: 5418bd7, a469579, 861d4f0, f0e3737. | -| 6 | Run Tests | 2026-03-30 | 23 passed, 0 failed, 0 skipped, 0 errors in 11.93s. Fixed: Cython __reduce_cython__ (clean rebuild), missing Pillow dep, relative MEDIA_DIR paths. Removed 14 dead/unreachable tests. Updated test-run skill to treat skips as blocking gate. | -| 7 | Refactor | 2026-03-31 | Engine-centric dynamic batch refactoring. Moved source to src/. Engine pipeline redesign: preprocess/postprocess/process_frames in base InferenceEngine, dynamic batching per engine (CoreML=1, TensorRT=GPU-calculated, ONNX=config). Fixed: video partial batch flush, image accumulation data loss, frame-is-None crash. Removed detect_single_image (POST /detect delegates to run_detect). Dead code: removed msgpack, serialize methods, unused constants/fields. Configurable classes.json + log paths, HTTP timeouts. 28 e2e tests pass. | - -## Key Decisions -- User chose to document existing codebase before proceeding -- Component breakdown: 4 components (Domain, Inference Engines, Inference Pipeline, API) -- Verification: 4 legacy issues found and documented (unused serialize/from_msgpack, orphaned queue declarations) -- Input data coverage approved at ~90% (Phase 1a) -- Test coverage approved at 85% (21/22 AC, 13/18 restrictions) with all gaps justified -- User chose refactor path (decompose tests → implement tests → refactor) -- Integration Tests Epic: AZ-137 -- Test Infrastructure: AZ-138 (5 pts) -- 10 integration test tasks decomposed: AZ-139 through AZ-148 (30 pts) -- Total: 11 tasks, 35 complexity points, 3 batches -- Phase 3 (Test Data Validation Gate) PASSED: 39/39 scenarios have data, 85% coverage, 0 tests removed -- Test data: 6 images, 3 videos, 1 ONNX model, 1 classes.json provided by user -- User confirmed dependency table and test data gate -- Jira MCP auth skipped — tickets not transitioned to In Testing -- Test run: removed 14 dead/unreachable tests (explicit @skip + runtime always-skip), added .c to .gitignore -- User chose to refactor (option A) — clean up legacy dead code -- User requested: move code to src/, thorough re-analysis, exhaustive refactoring list -- Refactoring round: 01-code-cleanup, automatic mode, 15 changes identified -- User feedback: analyze logical flow contradictions, not just static code. Updated refactor skill Phase 1 with logical flow analysis. -- User chose: split scope — engine refactoring as Step 7, architecture shift (streaming, DB config, media storage, Jetson) as Step 8 -- User chose: remove detect_single_image, POST /detect delegates to run_detect -- GPU memory fraction: 80% for inference, 20% buffer (Jetson 40% deferred to Step 8) - -## Last Session -date: 2026-03-31 -ended_at: Step 7 complete — all 11 todos done, 28 e2e tests pass -reason: Refactoring complete -notes: Engine-centric dynamic batch refactoring implemented. Source moved to src/. InferenceEngine base class now owns preprocess/postprocess/process_frames with per-engine max_batch_size. CoreML overrides preprocess (direct PIL, no blob reversal) and postprocess. TensorRT calculates max_batch_size from GPU memory (80% fraction) with optimization profiles for dynamic batch. All logical flow bugs fixed (LF-01 through LF-09). Dead code removed (msgpack, serialize, unused constants). POST /detect unified through run_detect. Next: Step 8 (architecture shift — streaming media, DB-backed config, media storage, Jetson support). - -## Blockers -- none