mirror of
https://github.com/Kpa-clawbot/meshcore-analyzer.git
synced 2026-06-04 10:22:01 +00:00
7106e1921e
Red commit:fc6ed65f(CI fails on `TestResolveRxTimeNaiveTimestampClamp`) Green commit:80bf1285## Problem California observers (UTC−7) had `last_seen` perpetually pinned ~7h behind wall-clock and rendered "Stale" in the UI despite active MQTT status traffic. Root cause: `parseEnvelopeTime` parses zone-less ISO timestamps (python `datetime.now().isoformat()`) as UTC, leaving a residual offset equal to the observer's UTC offset. The existing soft-clamp at `resolveRxTime` only caught the future-skew (UTC+N) mirror case. ## Fix — Option B (symmetric clamp) - `parseEnvelopeTime` now returns a `(time.Time, naive bool, error)` tuple so callers can tell zone-aware from zone-less parses. - `resolveRxTime` applies a 15-minute symmetric tolerance window for `naive==true` values: anything further off than 15 min collapses to ingest time and emits a warning log. - Well-behaved observers (Z-suffixed or explicit `±HH:MM` offset) are completely untouched regardless of skew — legitimate buffered uploads remain accurate to the second. Chose option B over option A (reject naive outright) because some observers may be sending naive *UTC* strings — those would suddenly lose their own time. Symmetric clamp preserves the well-synced naive case (< 15 min off) and rescues every other zone. ## Tests - New `TestResolveRxTimeNaiveTimestampClamp` covers naive past, naive future, naive w/ microseconds, Z-suffixed past (verbatim), offset-suffixed (canonicalized to UTC), naive within tolerance (verbatim). - `TestParseEnvelopeTime` updated for new signature, asserts `naive` flag. - All existing rxtime tests preserved (factory date, 30-day floor, 14h future, plausible past). - Red commit ran first, failed on assertions, then green commit makes everything pass. ## Operator visibility `naive timestamp "..." off by 7h, using ingest time` now appears in the ingestor log so operators can identify upstream observer scripts that should switch to `datetime.now(timezone.utc).isoformat()`. Fixes #1463 --------- Co-authored-by: openclaw-bot <bot@openclaw.local>