feat(selfhost): add clock-skew sample-age staleness gauge (#7000) - #7032
Conversation
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #7032 +/- ##
=======================================
Coverage 93.74% 93.74%
=======================================
Files 691 691
Lines 68658 68664 +6
Branches 18760 18761 +1
=======================================
+ Hits 64361 64367 +6
Misses 3302 3302
Partials 995 995
Flags with carried forward coverage won't be shown. Click here to find out more.
|
|
Tip ✅ LoopOver review result - approve/merge recommendedReview updated: 2026-07-17 19:04:04 UTC
Review summary Nits — 3 non-blocking
Decision drivers
Context & advisory signals — never blocks the verdict
Linked issue satisfactionAddressed Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://loopover.ai/docs/loopover-commands 🧪 Experimental — new and may change. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.
|
Summary
Adds a companion
loopover_clock_skew_sample_age_secondsgauge so an operator watching the clock-skew metric can tell a fresh reading from a stale one.loopover_clock_skew_secondsonly refreshes when a GitHub App JWT-mint call observes aDateheader; if token-mint activity stalls (e.g. a long-lived cached or broker-provided token means no fresh mint happens for a while), the existing gauge keeps reporting an old sample as if it were current — with no way to distinguish "clock is fine, just sampled a while ago" from "clock is fine right now."src/selfhost/clock-skew.ts: track the wall-clock time of the last successful sample alongsidelastSkewSeconds, updated in the same placerecordClockSkewFromResponsesets the skew; exposeclockSkewSampleAgeSeconds()returning the age in seconds, or a-1sentinel when no sample has landed yet — the same "never sampled" conventiond1-size-probe.ts/loopover_host_load_avg1_per_corealready use.resetClockSkewForTestresets the new state too. The existing skew-calculation logic is unchanged (the local timestamp is captured once and reused for both the skew and the sample time).src/server.ts: register the companion gauge next toloopover_clock_skew_seconds.src/selfhost/metrics.ts: declare the new gauge's HELP/TYPE metadata.Why
An old sample silently looking current defeats the point of the drift check (#3811): a dead NTP source could leave the clock drifting while the gauge shows a stale-but-fine reading. The age signal makes staleness observable, mirroring the freshness sentinel the D1 probe already established for exactly this class of problem.
Validation
npm run typecheck,npm run selfhost:validate-observability,npm run docs:drift-check— all green.test/unit/clock-skew.test.tsextended to 100% line + branch coverage on the changed module: the age starts at the-1never-sampled sentinel, reads0right after a sample and grows as time passes (fake timers), stays anchored to the last GOOD sample when a response is ignored (a missing/invalidDateheader must not reset the sample time), and returns to-1after reset.Closes #7000