SR-187: Ban datetime.utcnow() — Enforce UTC-aware datetimes
Why this is critical
Python 3.12 deprecated datetime.utcnow() (DeprecationWarning), will remove in 3.14. More critically for our domain: naive datetimes are ambiguous when compared against UTC-aware datetimes. We found 6 production instances:
survey/captcha/fallback_chain.py:189,197 # Survey captcha timestamps
survey/daemon/answer_engine.py:1005 # Answer engine audit log
survey/daemon/survey_agent_graph.py:173,235 # LangGraph state: started_at, completed_at
These timestamps are compared against UTC-aware DB timestamps — silent off-by-tz is possible.
Solution
Add datetime.utcnow to scripts/check_banned_patterns.py banlist. One PR refactors the 6 sites:
# OLD
datetime.utcnow().isoformat()
# NEW
from datetime import datetime, timezone
datetime.now(timezone.utc).isoformat()
Acceptance Criteria
Priority
critical — blocks Python 3.14 upgrade, creates silent timezone bugs today.
SR-187: Ban
datetime.utcnow()— Enforce UTC-aware datetimesWhy this is critical
Python 3.12 deprecated
datetime.utcnow()(DeprecationWarning), will remove in 3.14. More critically for our domain: naive datetimes are ambiguous when compared against UTC-aware datetimes. We found 6 production instances:These timestamps are compared against UTC-aware DB timestamps — silent off-by-tz is possible.
Solution
Add
datetime.utcnowtoscripts/check_banned_patterns.pybanlist. One PR refactors the 6 sites:Acceptance Criteria
check_banned_patterns.pyextended with regex fordatetime.utcnow()datetime.utcnow()in production code fails path-guarddatetime(..., tzinfo=timezone.utc)Priority
critical — blocks Python 3.14 upgrade, creates silent timezone bugs today.