Skip to content

Enable mypy --strict-optional and fix nullability gaps #69

@bradjin8

Description

@bradjin8

Repository: cppa-cursor-browser
Assignee: Brad @bradjin8
Points: 5
Severity: High

Problem

mypy is configured with --no-strict-optional, which disables null-checking on Optional types throughout the codebase. The bubble-processing pipeline types its intermediate data as dict[str, Any] — a deliberate tradeoff for parsing undocumented Cursor schemas — but the consequence is that mypy cannot enforce null-checking on values extracted from these dictionaries. The static type system abdicates at the point where the data is least predictable. This is the root of the "Silent Failure Chain" compound: type-system gaps enable inconsistent exception handling, which enables silent data loss.

Acceptance Criteria

  • --no-strict-optional is removed from the mypy configuration (in pyproject.toml or mypy.ini)
  • --strict-optional is effectively enabled (it is mypy's default)
  • All resulting mypy errors are fixed with proper Optional typing and explicit null checks
  • No new # type: ignore suppressions are added without inline justification comments
  • The fix does not change runtime behavior — only type annotations and guard clauses
  • mypy passes clean in CI
  • Tests pass in CI
  • PR approved by at least 1 reviewer

Implementation Notes

Run mypy --strict-optional locally first to identify all new errors. The majority will be in services/workspace_tabs.py and services/workspace_listing.py where dict.get() returns Optional values that are used without null checks. Fix patterns: add explicit if value is not None: guards, use dict.get(key, default) with typed defaults, or narrow types with assertions where the value is structurally guaranteed. The models/ frozen dataclasses with their from_dict validators are already null-aware — the gaps are in the service layer that consumes raw dicts. Expect 20-50 mypy errors. Batch the fixes by file to keep the diff reviewable.

References

  • Eval finding: Test 6 (Type Safety) — root of the "Invisible Pipeline Failures" compound (T6+T7)
  • Related files: pyproject.toml (mypy config), services/workspace_tabs.py, services/workspace_listing.py, services/workspace_db.py, models/conversation.py

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions