Skip to content

test(stream-consumer): fix monotonic-epoch flake blocking fork CI - #32

Merged
bbasketballer75 merged 1 commit into
mainfrom
fix/fork-stream-consumer-monotonic
Aug 4, 2026
Merged

test(stream-consumer): fix monotonic-epoch flake blocking fork CI#32
bbasketballer75 merged 1 commit into
mainfrom
fix/fork-stream-consumer-monotonic

Conversation

@bbasketballer75

Copy link
Copy Markdown
Owner

Why this exists

Backport of NousResearch/hermes-agent#78107, applied here so this fork's CI stops failing slice 8/8 on every PR while the upstream one is in review. #30 is currently blocked by exactly this.

The bug

gateway/stream_consumer.py:1718 computes preview age as:

age = time.monotonic() - self._message_created_ts

monotonic()'s epoch is arbitrary — on Linux, boot. So _message_created_ts = 0.0 does not mean "long ago"; it means "monotonic() seconds ago". On a freshly-booted runner that's a handful of seconds, the age falls under the 60s threshold, fresh-final never fires, and adapter.send.call_count is 1 instead of 2.

That explains the intermittency exactly: passed on #26/#27/#28/#29, failed on #25 and #30 — purely a function of runner uptime, not randomness. I originally wrote it off as a flake and re-ran it; that was wrong.

Verification

  • File: 10/10
  • With time.monotonic patched to 12.0, simulating a host booted 12 seconds ago: the fix passes where the old form fails at line 79 — the exact CI failure

No assertion weakened, no production code changed (production is correct — only the test's notion of "old" was wrong).

Note on the label gate

This touches only tests/, so it does not trip the ci-reviewed gate and can merge without a label. #30 does touch .github/workflows/** and still needs one.

🤖 Generated with Claude Code

Backport of the fix proposed upstream in NousResearch#78107,
applied here so this fork's CI stops failing slice 8/8 on every PR while that
one is in review.

`stream_consumer.py:1718` computes preview age as
`time.monotonic() - self._message_created_ts`. monotonic()'s epoch is
arbitrary (on Linux, boot), so setting `_message_created_ts = 0.0` does not
mean "long ago" — it means "monotonic() seconds ago". On a freshly-booted
runner that is a handful of seconds, so the age falls under the 60s threshold,
fresh-final never fires, and `adapter.send.call_count` is 1 instead of 2.

That is why it is intermittent: it passed on #26/#27/#28/#29 and failed on
#25 and #30, purely as a function of runner uptime.

Fixed by anchoring to the same clock the production code reads. No assertion
weakened, no production code changed.

Verified: 10/10 in the file; and with time.monotonic patched to 12.0 to
simulate a host booted 12 seconds ago, the test passes where the old form
fails at line 79 — the exact CI failure.

Touches only tests/, so it does not trip the ci-reviewed workflow gate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 4, 2026 02:21

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Ready to approve

The change is a targeted, production-faithful test fix that removes a confirmed nondeterminism without weakening assertions or altering runtime behavior.

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Pull request overview

Fixes a CI-only flake in the stream-consumer “fresh final” regression tests by ensuring the test’s notion of an “old preview” uses the same clock as the production code (time.monotonic()), avoiding dependence on runner uptime.

Changes:

  • Add a monotonic-time based helper (_stale_ts) and constant to generate a reliably “old” _message_created_ts.
  • Replace consumer._message_created_ts = 0.0 in affected tests with _stale_ts() to make the age gate deterministic across hosts.
File summaries
File Description
tests/gateway/test_stream_consumer_fresh_final.py Makes “preview is old” setup monotonic-clock-correct to eliminate uptime-based test flakiness.
Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 0
  • Review effort level: Lite

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

@bbasketballer75
bbasketballer75 merged commit b3f4354 into main Aug 4, 2026
44 checks passed
@bbasketballer75
bbasketballer75 deleted the fix/fork-stream-consumer-monotonic branch August 4, 2026 02:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants