theloom/viz/temporal.py:15 filters events with at > as_of, where at is Event.timestamp — a datetime.isoformat() string (…816000+00:00) — while asOf arrives in the wire format (…816Z). Two different shapes, compared as strings.
The codebase already has the guard against exactly this: _entry_id_to_wire_iso (theloom/store/events.py:247), and entry_id_timestamp's docstring (events.py:208-214) explains why cross-shape comparisons must use the wire form.
Today the mismatch is benign by accident: when prefixes tie through the millisecond digits, '0' < 'Z' errs toward inclusion, which is the harmless direction for an as-of read. But it is the precise hazard the helper exists to prevent, and any future consumer comparing the other direction inherits it silently.
Fix: normalize both sides to the wire shape at the comparison (or render Event.timestamp in wire form at construction — check blast-radius on other Event.timestamp consumers first). Pin with a test whose event and pivot tie through the millisecond.
(Found while diagnosing the flaky test_as_of_truncates_temporal_events, fixed separately in PR #44 — that flake was clock-domain skew; this is the adjacent format inconsistency.)
theloom/viz/temporal.py:15filters events withat > as_of, whereatisEvent.timestamp— adatetime.isoformat()string (…816000+00:00) — whileasOfarrives in the wire format (…816Z). Two different shapes, compared as strings.The codebase already has the guard against exactly this:
_entry_id_to_wire_iso(theloom/store/events.py:247), andentry_id_timestamp's docstring (events.py:208-214) explains why cross-shape comparisons must use the wire form.Today the mismatch is benign by accident: when prefixes tie through the millisecond digits,
'0' < 'Z'errs toward inclusion, which is the harmless direction for an as-of read. But it is the precise hazard the helper exists to prevent, and any future consumer comparing the other direction inherits it silently.Fix: normalize both sides to the wire shape at the comparison (or render
Event.timestampin wire form at construction — check blast-radius on otherEvent.timestampconsumers first). Pin with a test whose event and pivot tie through the millisecond.(Found while diagnosing the flaky
test_as_of_truncates_temporal_events, fixed separately in PR #44 — that flake was clock-domain skew; this is the adjacent format inconsistency.)