289 lines
12 KiB
Markdown
289 lines
12 KiB
Markdown
## Task F4: Scope Fidelity Check — Issues (2026-02-27)
|
|
|
|
### Non-compliance / drift items
|
|
|
|
1. `opengait/demo/sconet_demo.py` forward return contract drift: returns tensor `label` and tensor `confidence` instead of scalar int/float payload shape described in plan.
|
|
2. `opengait/demo/window.py` `fill_level` drift: implemented as integer count, while plan specifies len/window float ratio.
|
|
3. `opengait/demo/output.py` result schema drift: `window` serialized as list (`create_result`), but plan DoD schema states integer field.
|
|
4. `opengait/demo/pipeline.py` CLI drift: `--source` configured with default instead of required flag.
|
|
5. `opengait/demo/pipeline.py` behavior drift: no FPS logging loop (every 100 frames) found.
|
|
6. `tests/demo/test_pipeline.py` missing planned FPS benchmark scenario.
|
|
7. `tests/demo/test_nats.py` hardcodes `NATS_PORT = 4222`, conflicting with plan guidance to avoid hardcoded port in tests.
|
|
|
|
### Scope creep / unexplained files
|
|
|
|
- Root-level unexplained artifacts present: `EOF`, `LEOF`, `ENDOFFILE`.
|
|
|
|
### Must NOT Have guardrail status
|
|
|
|
- Guardrails mostly satisfied (no `torch.distributed`, no BaseModel in demo, no TensorRT/DeepStream, no GUI/multi-person logic); however overall scope verdict remains REJECT due to 7 functional/spec drifts above.
|
|
|
|
## Blocker Fix: ScoNet checkpoint load mismatch (2026-02-27)
|
|
|
|
- Reproduced blocker with required smoke command: strict load failed with missing `backbone.*` / unexpected `Backbone.forward_block.*` (plus `FCs.*`, `BNNecks.*`).
|
|
- Root cause: naming convention drift between historical ScoNet checkpoint serialization and current `ScoNetDemo` module attribute names.
|
|
- Resolution: deterministic key normalization for known legacy prefixes while preserving strict load behavior and clear runtime error wrapping when incompatibility remains.
|
|
|
|
|
|
|
|
## 2026-02-27: Scope-Fidelity Drift Fix (F4) - Task 1 - FIXED
|
|
|
|
### Issues Identified and Fixed
|
|
|
|
1. **CLI --source not required** (FIXED)
|
|
- **Location**: Line 261 in `opengait/demo/pipeline.py`
|
|
- **Issue**: `--source` had `default="0"` instead of being required
|
|
- **Fix**: Changed to `required=True`
|
|
- **Impact**: Users must now explicitly provide --source argument
|
|
|
|
2. **Missing FPS logging** (FIXED)
|
|
- **Location**: `run()` method in `opengait/demo/pipeline.py`
|
|
- **Issue**: No FPS logging in the main processing loop
|
|
- **Fix**: Added frame counter and FPS logging every 100 frames
|
|
- **Impact**: Users can now monitor processing performance
|
|
|
|
### No Other Issues
|
|
|
|
- No type errors introduced
|
|
- No runtime regressions
|
|
- Error handling semantics preserved
|
|
- JSON output schema unchanged
|
|
- Window/predict logic unchanged
|
|
[2026-02-27T00:44:25+08:00] Removed unexplained root files: EOF, LEOF, ENDOFFILE (scope-fidelity fix)
|
|
|
|
|
|
## 2026-02-27: NATS Port Fix - Type Narrowing Issue (FIXED)
|
|
|
|
### Issue
|
|
- `sock.getsockname()` returns `Any` type causing basedpyright warning
|
|
- Previous fix with `int()` cast still leaked Any in argument position
|
|
|
|
### Fix Applied
|
|
- Used `typing.cast(tuple[str, int], sock.getsockname())` for explicit type narrowing
|
|
- Added intermediate variable with explicit type annotation
|
|
|
|
### Verification
|
|
- `uv run basedpyright tests/demo/test_nats.py`: 0 errors, 0 warnings, 0 notes
|
|
- `uv run pytest tests/demo/test_nats.py -q`: 9 passed, 2 skipped
|
|
|
|
### Files Modified
|
|
- `tests/demo/test_nats.py` only (line 29-30 in `_find_open_port()`)
|
|
|
|
## 2026-02-27: Test Expectations Mismatch After fill_level Fix
|
|
|
|
After changing `fill_level` to return float ratio instead of integer count,
|
|
5 tests in `tests/demo/test_window.py` now fail due to hardcoded integer expectations:
|
|
|
|
1. `test_window_fill_and_ready_behavior` - expects `fill_level == i + 1` (should be `(i+1)/5`)
|
|
2. `test_underfilled_not_ready` - expects `fill_level == 9` (should be `0.9`)
|
|
3. `test_track_id_change_resets_buffer` - expects `fill_level == 5` (should be `1.0`)
|
|
4. `test_frame_gap_reset_behavior` - expects `fill_level == 5` (should be `1.0`)
|
|
5. `test_reset_clears_all_state` - expects `fill_level == 0` (should be `0.0`)
|
|
|
|
These tests need updating to expect float ratios instead of integer counts.
|
|
|
|
## 2026-02-27: Test Assertions Updated for fill_level Ratio Contract
|
|
|
|
**Status:** Test file updated, pending runtime fix
|
|
|
|
### Changes Made
|
|
Updated `tests/demo/test_window.py` assertions to expect float ratios (0.0..1.0) instead of integer frame counts:
|
|
|
|
| Test | Old Assertion | New Assertion |
|
|
|------|---------------|---------------|
|
|
| `test_window_fill_and_ready_behavior` | `== i + 1` | `== (i + 1) / 5` |
|
|
| `test_window_fill_and_ready_behavior` | `== 5` | `== 1.0` |
|
|
| `test_underfilled_not_ready` | `== 9` | `== 0.9` |
|
|
| `test_track_id_change_resets_buffer` | `== 5` | `== 1.0` |
|
|
| `test_track_id_change_resets_buffer` | `== 1` | `== 0.2` |
|
|
| `test_frame_gap_reset_behavior` | `== 5` | `== 1.0` |
|
|
| `test_frame_gap_reset_behavior` | `== 1` | `== 0.2` |
|
|
| `test_reset_clears_all_state` | `== 0` | `== 0.0` |
|
|
|
|
### Blocker
|
|
Tests cannot pass until `opengait/demo/window.py` duplicate `fill_level` definition is removed (lines 208-210).
|
|
|
|
### Verification Results
|
|
- basedpyright: 0 errors (18 pre-existing warnings unrelated to this change)
|
|
- pytest: 5 failed, 14 passed (failures due to window.py bug, not test assertions)
|
|
|
|
|
|
## Task F4 Re-Audit: Remaining Issues (2026-02-27)
|
|
|
|
### Status update for previous F4 drifts
|
|
|
|
Fixed:
|
|
- `opengait/demo/pipeline.py` source flag now required (`line 268`)
|
|
- `opengait/demo/pipeline.py` FPS logging present (`lines 213-232`)
|
|
- `opengait/demo/window.py` `fill_level` now ratio float (`lines 205-207`)
|
|
- `tests/demo/test_nats.py` dynamic port allocation via `_find_open_port()` (`lines 24-31`) and fixture-propagated port
|
|
- Root artifact files `EOF`, `LEOF`, `ENDOFFILE` removed (not found)
|
|
|
|
Still open:
|
|
1. **Schema mismatch**: `opengait/demo/output.py:363` emits `"window": list(window)`; plan DoD expects integer `window` field.
|
|
2. **Missing planned FPS benchmark test**: `tests/demo/test_pipeline.py` contains no FPS benchmark scenario from Task 12 plan section.
|
|
3. **ScoNetDemo sequence contract drift in tests**: `tests/demo/test_sconet_demo.py:42,48` uses seq=16 fixtures, not the 30-frame window contract emphasized by plan.
|
|
|
|
### Current re-audit verdict basis
|
|
|
|
- Remaining blockers: 3
|
|
- Scope state: not clean
|
|
- Verdict remains REJECT until these 3 are resolved or plan is amended by orchestrator.
|
|
## 2026-02-27T01:11:58+08:00 - Fixed: Sequence Length Drift in Test Fixtures
|
|
|
|
**File:** tests/demo/test_sconet_demo.py
|
|
**Issue:** Fixtures used seq=16 but config specifies frames_num_fixed: 30
|
|
**Fix:** Updated dummy_sils_batch and dummy_sils_single fixtures to use seq=30
|
|
**Status:** ✅ Resolved - pytest passes (21/21), basedpyright clean (0 errors)
|
|
|
|
|
|
## 2026-02-27: Window Schema Fix - output.py (F4 Blocker) - FIXED
|
|
|
|
**Issue:** `opengait/demo/output.py:363` emitted `"window": list(window)`, conflicting with plan DoD schema expecting integer field.
|
|
|
|
**Fix Applied:**
|
|
- Type hint: `window: int | tuple[int, int]` (backward compatible input)
|
|
- Serialization: `"window": window if isinstance(window, int) else window[1]`
|
|
- Docstring examples updated to show integer format
|
|
|
|
**Status:** ✅ Resolved
|
|
- basedpyright: 0 errors
|
|
- pytest: 9 passed, 2 skipped
|
|
|
|
## 2026-02-27: Task 12 Pipeline Test Alignment - Issues
|
|
|
|
### Initial Failure (expected RED phase)
|
|
- `uv run pytest tests/demo/test_pipeline.py -q` failed in happy-path and max-frames tests because `_assert_prediction_schema` still expected `window` as `list[int, int]` while runtime emits integer end-frame.
|
|
- Evidence: assertion failure `assert isinstance(window_obj, list)` with observed payload values like `"window": 12`.
|
|
|
|
### Resolution
|
|
- Updated only `tests/demo/test_pipeline.py` schema assertion to require `window` as non-negative `int`.
|
|
- Added explicit FPS benchmark scenario with conservative threshold and CI stability guards.
|
|
|
|
### Verification
|
|
- `uv run pytest tests/demo/test_pipeline.py -q`: 5 passed
|
|
- `uv run basedpyright tests/demo/test_pipeline.py`: 0 errors, 0 warnings, 0 notes
|
|
|
|
|
|
## Task F4 Final Re-Audit: Issues Update (2026-02-27)
|
|
|
|
### Previously open blockers now closed
|
|
|
|
1. `opengait/demo/output.py` window schema mismatch — **CLOSED** (`line 364` now emits integer window).
|
|
2. `tests/demo/test_pipeline.py` missing FPS benchmark test — **CLOSED** (`test_pipeline_cli_fps_benchmark_smoke`, lines `109-167`).
|
|
3. `tests/demo/test_sconet_demo.py` seq=16 fixtures — **CLOSED** (fixtures now seq=30 at lines `42,48`).
|
|
|
|
### Guardrail status
|
|
|
|
- `opengait/demo/` has no `torch.distributed` usage and no `BaseModel` usage.
|
|
- Root artifact files `EOF/LEOF/ENDOFFILE` are absent.
|
|
|
|
### Current issue count
|
|
|
|
- Remaining blockers: 0
|
|
- Scope issues: 0
|
|
- F4 verdict: APPROVE
|
|
|
|
## Task: Fix NATS Test Schema and Port Mapping (2026-02-27)
|
|
|
|
### Oracle-Reported Issues
|
|
|
|
1. **Schema Validator Expected List, Runtime Emits Int**
|
|
- Location: `_validate_result_schema` in `tests/demo/test_nats.py`
|
|
- Problem: Validator checked `window` as `list[int]` with length 2
|
|
- Runtime: `create_result` in `opengait/demo/output.py` emits `window` as `int`
|
|
- Root Cause: Test schema drifted from runtime contract
|
|
- Fix: Updated validator to check `isinstance(window, int)` and `window >= 0`
|
|
|
|
2. **Docker Port Mapping Incorrect**
|
|
- Location: `_start_nats_container` in `tests/demo/test_nats.py` (line 94)
|
|
- Problem: Used `-p {port}:{port}` which mapped host port to same container port
|
|
- NATS Container: Listens on port 4222 internally
|
|
- Fix: Changed to `-p {port}:4222` to map host dynamic port to container port 4222
|
|
|
|
### Resolution
|
|
|
|
Both issues fixed in `tests/demo/test_nats.py` only. No runtime changes required.
|
|
|
|
Verification:
|
|
- basedpyright: 0 errors, 0 warnings
|
|
- pytest: 9 passed, 2 skipped (Docker unavailable)
|
|
|
|
## Fix: Remove Stale Port Mapping (2026-02-27)
|
|
|
|
**Bug:** Duplicate port mappings in `_start_nats_container` caused Docker to receive invalid arguments.
|
|
**Resolution:** Removed stale `f"{port}:{port}"` line, keeping only `f"{port}:4222"`.
|
|
**Status:** Fixed and verified.
|
|
|
|
## Fix: Remove Duplicate Image Arg (2026-02-27)
|
|
|
|
**Bug:** Docker command had `"nats:latest", "nats:latest"` (duplicate).
|
|
**Resolution:** Kept exactly one `"nats:latest"`.
|
|
**Status:** Fixed and verified.
|
|
|
|
## Oracle Review #2 (2026-02-27): Residual Non-Blocking Issues
|
|
|
|
### M1: Pending asyncio task warning (Minor)
|
|
- Location: `opengait/demo/output.py:196`
|
|
- Symptom: "Task was destroyed but it is pending!" on NATS connection failure
|
|
- Fix: Cancel in-flight coroutine in `_stop_background_loop()` before stopping event loop
|
|
- Impact: Cosmetic only
|
|
|
|
### M2: Duplicate docstring line in create_result (Trivial)
|
|
- Location: `opengait/demo/output.py:349-350`
|
|
- Fix: Remove duplicate "Frame window [start, end]" line
|
|
|
|
### M3: Incorrect label examples in create_result docstring (Minor)
|
|
- Location: `opengait/demo/output.py:345`
|
|
- Says "normal", "scoliosis" but labels are "negative", "neutral", "positive"
|
|
- Fix: Update docstring to match LABEL_MAP
|
|
|
|
|
|
## 2026-02-27: Workspace Hygiene Cleanup
|
|
|
|
Removed scope-creep artifacts from prior delegated runs:
|
|
- Deleted `.sisyphus/notepads/demo-tensor-fix/` (entire folder)
|
|
- Deleted `assets/sample.mp4`
|
|
|
|
Repository no longer contains these untracked files.
|
|
|
|
## Blocker: Task 11 Sample Video Acceptance Items (2026-02-27)
|
|
|
|
**Status:** BLOCKED - Pending user-provided sample video
|
|
|
|
**Remaining unchecked acceptance criteria from Task 11:**
|
|
1. `./assets/sample.mp4` (or `.avi`) exists
|
|
2. Video has ≥60 frames
|
|
3. Playable with OpenCV validation command
|
|
|
|
**Unblock condition:** Sample video file provided by user and all 3 criteria above pass validation.
|
|
|
|
**Note:** User explicitly stated they will provide sample video later; no further plan items remain outside these blocked sample-video checks.
|
|
## Heartbeat Check (2026-02-27)
|
|
|
|
- Continuation check: 3 unchecked plan items remain
|
|
- Still no `*.mp4/*.avi/*.mov/*.mkv` files in repo
|
|
- **Unblock condition:** User-provided sample video with >=60 frames and OpenCV-readable
|
|
|
|
|
|
## Fix: BBox/Mask Coordinate Mismatch (2026-02-27)
|
|
|
|
### Issue
|
|
Demo pipeline produced no classifications for YOLO segmentation outputs because bbox and mask were in different coordinate spaces.
|
|
|
|
### Resolution
|
|
Fixed in `opengait/demo/window.py` - `select_person()` now scales bbox from frame space to mask space using YOLO's `orig_shape` metadata.
|
|
|
|
### Verification
|
|
- All tests pass (33 passed, 4 skipped)
|
|
- Smoke test on provided video yields 56 classifications from 60 frames
|
|
- Non-zero confidence values confirmed
|
|
|
|
### Status
|
|
RESOLVED
|
|
## 2026-02-27: Sample Video Blocker Resolved
|
|
|
|
- Previous blocker (missing sample video) is no longer active.
|
|
- `assets/sample.mp4` now present and playable via OpenCV with 227 frames.
|
|
- No remaining open checklist items in `.sisyphus/plans/sconet-pipeline.md` after checkbox update.
|