0d0b433a2e
Phase 3 (partial): self.files guarantee (FR4 row 1) Before: 13 hasattr(f, ...) defensive checks in src/app_controller.py After: 0 (self.files is GUARANTEED List[FileItem] per init at 1996-2005) Delta: -13 sites Per the spec's FR4 row 1: 'After Phase 3, self.files is GUARANTEED List[FileItem]. Every hasattr(f, "path") check is redundant. Remove it.' The init code at src/app_controller.py:1996-2005 already does the correct isinstance check + FileItem.from_dict() pattern, so all 13 hasattr checks on self.files / self.context_files are redundant defensive code. Verification: - audit_weak_types --strict: OK (107 <= 112 baseline) - py_check_syntax src/app_controller.py: OK - 59 tests pass (type_aliases, openai_schemas, rag_engine, file_item, etc.) OUT OF SCOPE (deferred): - 18 hasattr(f, 'path') checks in src/gui_2.py (Phase 3 follow-up) - Phase 4: _do_generate return type - Phase 5: rag_engine.search() return type - Phase 6: 30 Optional[T] returns - Phase 7: 59 Any params + 10 dict[str, Any] params See TRACK_COMPLETION_cruft_elimination_20260627.md for full scope.