# Batch 18 — Cycle 1 Implementation Report

**Tasks**: AZ-659, AZ-660, AZ-661
**Completed**: 2026-05-20
**Status**: All tests pass; code review PASS_WITH_WARNINGS; committed `0854d3b`

---

## AZ-659 — frame_ingest publisher (3 pts)

**Files added/changed**:
- `crates/frame_ingest/src/internal/publisher.rs` — `FramePublisher`, `FrameReceiver`, `ConsumerId`, `PublisherStats`
- `crates/frame_ingest/src/internal/mod.rs` — exports `publisher`
- `crates/frame_ingest/src/lib.rs` — `FrameIngestHandle` extended with `subscribe_as`, `publisher`, `dropped_frames`, `publishes_total`
- `crates/frame_ingest/tests/publisher.rs` — AC-1/2/3 integration tests

**ACs**: All passing.

---

## AZ-660 — detection_client gRPC bi-directional stream (5 pts)

**Files added/changed**:
- `crates/detection_client/Cargo.toml` — added `tonic`, `prost`, `tonic-prost-build`, `protoc-bin-vendored`
- `crates/detection_client/build.rs` — proto codegen via `tonic-prost-build`
- `crates/detection_client/proto/detections.proto` — gRPC contract (FrameRequest / DetectionResponse bi-di stream)
- `crates/detection_client/src/internal/mod.rs` — module registry
- `crates/detection_client/src/internal/proto.rs` — generated code re-export
- `crates/detection_client/src/internal/budget.rs` — `BudgetTracker` (drop-oldest VecDeque, default capacity 2)
- `crates/detection_client/src/internal/stats.rs` — `DetectionStats` (lock-free AtomicU64 counters)
- `crates/detection_client/src/internal/runtime.rs` — supervisor + `run_stream_session` with bounded backoff reconnect
- `crates/detection_client/src/lib.rs` — `DetectionClient`, `DetectionClientConfig`, `DetectionClientHandle`, `DetectionEvent`, `ConnectionState`
- `crates/detection_client/tests/stream.rs` — AC-1/2/3/4 integration tests (fixture in-process gRPC server)

**ACs**: All passing.

---

## AZ-661 — schema validation + model_version + latency degradation (2 pts)

Implemented inside the same `detection_client` crates (AC-660 and AC-661 share the same modules):
- `src/internal/latency.rs` — `LatencyWindow` ring-buffer + `DegradationTransition` latch
- `src/internal/runtime.rs::handle_response` — schema version check, model_version latch, Tier1 degradation evaluation after every response
- `crates/detection_client/tests/stream.rs` — AC-1/2/3 integration tests

**ACs**: All passing.

---

## Code Review

**Verdict**: PASS_WITH_WARNINGS — see `_docs/03_implementation/reviews/batch_18_review.md`.

Findings:
- F1 (Medium, fixed): dead code in `handle_response` (`let now`, `let _ = in_flight`) removed.
- F2–F4: Low findings, no action required this batch.

---

## Architecture / Doc Updates

- `_docs/02_document/module-layout.md` — `frame_ingest` and `detection_client` sections updated to reflect actual streaming API.

---

## Remaining tasks in `todo/`

9 tasks remaining across 3 components (movement_detector, semantic_analyzer, scan_controller).
