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
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
Repository: cppa-cursor-browser
Assignee: Brad @bradjin8
Points: 5
Severity: High
Problem
mypy is configured with
--no-strict-optional, which disables null-checking onOptionaltypes throughout the codebase. The bubble-processing pipeline types its intermediate data asdict[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-optionalis removed from the mypy configuration (inpyproject.tomlormypy.ini)--strict-optionalis effectively enabled (it is mypy's default)Optionaltyping and explicit null checks# type: ignoresuppressions are added without inline justification commentsImplementation Notes
Run
mypy --strict-optionallocally first to identify all new errors. The majority will be inservices/workspace_tabs.pyandservices/workspace_listing.pywheredict.get()returnsOptionalvalues that are used without null checks. Fix patterns: add explicitif value is not None:guards, usedict.get(key, default)with typed defaults, or narrow types with assertions where the value is structurally guaranteed. Themodels/frozen dataclasses with theirfrom_dictvalidators 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
pyproject.toml(mypy config),services/workspace_tabs.py,services/workspace_listing.py,services/workspace_db.py,models/conversation.py