Skip to content

[aw][code health] VS Code log timestamps are naive (no tzinfo), diverging from the codebase's aware-datetime convention #993

@microsasa

Description

@microsasa

Root Cause

vscode_parser._parse_vscode_log_from_offset parses timestamps with datetime.fromisoformat(ts_str), where ts_str is extracted from log lines like 2024-01-15 10:30:45.123. Because the log format contains no UTC offset or timezone designator, fromisoformat returns a naive datetime (no tzinfo).

These naive timestamps propagate to:

  • VSCodeRequest.timestamp: datetime — stored in every parsed request
  • VSCodeLogSummary.first_timestamp: datetime | None
  • VSCodeLogSummary.last_timestamp: datetime | None

The rest of the codebase (models.py) uses aware datetimes throughout, with ensure_aware() attached to UTC whenever a datetime is produced or compared. SessionSummary.start_time, end_time, last_resume_time, etc. are all aware.

Impact

Mixing naive and aware datetimes raises TypeError: can't compare offset-naive and offset-aware datetimes at runtime. Currently this doesn't happen because vscode timestamps are only used within the vscode subsystem (formatted for display in vscode_report.py, compared with each other in _update_vscode_summary). But:

  1. The type annotation datetime on VSCodeRequest.timestamp and VSCodeLogSummary.first_timestamp/last_timestamp gives callers no indication that these are naive — anyone who compares them with a SessionSummary timestamp would get a runtime TypeError.
  2. Merging vscode summaries with session summaries (a likely future feature) would silently surface this latent bug.
  3. The codebase has an established convention: all datetime values at module boundaries are aware UTC. VSCodeRequest and VSCodeLogSummary violate this contract.

Investigation Required

The VS Code log timestamps use the local system time (not UTC), so simply calling ensure_aware() (which assumes UTC) would produce incorrect wall-clock values. The correct fix requires one of:

  1. Attach local timezone: use datetime.fromisoformat(ts_str).astimezone(UTC) to convert local time → UTC (correct, but requires datetime.astimezone() which adds local_timezone overhead).
  2. Document as local-naive, isolate them: keep timestamps naive but add a LocalNaiveDatetime type alias or a wrapper dataclass field with a docstring/comment explicitly marking them as local-time naive, and add a lint guard preventing comparison with aware datetimes outside the vscode subsystem.
  3. Store as UTC from the moment of parsing and accept that the display format will show UTC instead of local time. Evaluate whether this matters for vscode_report.py display.

Option 1 is the cleanest. After conversion, VSCodeRequest.timestamp and VSCodeLogSummary.first/last_timestamp become aware UTC datetimes, consistent with the rest of the codebase, and vscode_report.py's strftime calls will continue working correctly (UTC times are still reasonable for a usage report).

Fix Specification

In _parse_vscode_log_from_offset, replace:

ts = datetime.fromisoformat(ts_str)

with:

ts = datetime.fromisoformat(ts_str).astimezone(UTC)

and add from datetime import UTC to the existing import if not already present (it is already imported in models.py).

Testing Requirements

Add tests to test_vscode_parser.py:

  1. test_parsed_request_timestamp_is_aware: parse a synthetic log line and assert req.timestamp.tzinfo is not None.
  2. test_vscode_summary_timestamps_are_aware: call build_vscode_summary([req]) and assert summary.first_timestamp.tzinfo is not None and summary.last_timestamp.tzinfo is not None.
  3. test_vscode_timestamps_comparable_with_session_timestamps: compare VSCodeLogSummary.first_timestamp with a known aware datetime to verify no TypeError is raised.

Existing tests that compare vscode timestamps should continue to pass after the conversion (they test relative ordering, not absolute UTC values).

Generated by Code Health Analysis · ● 5.4M ·

Metadata

Metadata

Assignees

No one assigned

    Labels

    awCreated by agentic workflowaw-dispatchedIssue has been dispatched to implementercode-healthCode cleanup and maintenance

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions