Run the latest-versions canary on a nightly schedule, not only on tag refs

Author: DouweMCreated Sep 17, 2026Updated Sep 18, 2026

Summary

The latest-versions-canary job runs only on tag refs, so by construction it can only ever fail during a release. It should run on a schedule (nightly) so dependency drift surfaces with days to act on it, rather than at the moment we are trying to ship.

#8439 made it advisory via allowed-failures so it stops blocking releases. That was a stopgap to unblock a security release, not the fix. Advisory-on-tags is arguably a worse place for the signal than blocking-on-tags: it now produces a red mark at the exact moment everyone is focused on shipping, with nothing obliging anyone to read it.

Why the canary matters

It is the only job that tests what a fresh pip install pydantic-ai actually resolves. Normal CI tests the lockfile, which can be months stale. In its 2026-09-16 run it exercised cohere 5.20.6 to 7.1.1 (two major versions) and logfire 4.40.0 to 5.1.0, both of which our declared ranges permit and neither of which the lockfile covers. That is real coverage of a real gap, which is why the answer is to move it rather than drop it.

What prompted this

On 2026-09-16 the canary blocked the v2.44.0 security release. All 7 failures on both 3.10 and 3.14 were inline-snapshot mismatches in tests/models/test_github_copilot.py, of one shape:

actual:   usage=RequestUsage(cost=Decimal('0.000125'), input_tokens=20, ...)
expected: usage=RequestUsage(input_tokens=20, ...)

A newer genai-prices populates RequestUsage.cost where it previously left it unset. That is additive, not a break: 13,990 of 13,997 tests passed at latest versions. No user-facing failure, but it held up a coordinated security release for close to an hour.

A 2026-09-04 maintainer discussion had already concluded this check should move out of the release flow into normal CI, after it tripped most days that week on upstream drift. That conclusion was never implemented.

Proposal

  1. Run latest-versions-canary on a nightly schedule trigger against main, instead of (or in addition to) tag refs.
  2. Keep it off the release gate, as #8439 now has it.
  3. Route a failure somewhere it gets seen, so a nightly red does not just accumulate.

The point of seeing drift early is that it enables the right response. As put in the 2026-09-04 discussion: if something breaks inside a version range we claim to support, that is a signal to set a maximum on the range. You can only make that call with days of warning, not minutes.

Follow-up in the same area

  • The cost snapshots in tests/models/test_github_copilot.py are stale against current genai-prices and will keep failing the canary until refreshed. They cannot simply be regenerated, since the locked version does not populate cost and the regular test job would then fail. Worth deciding whether these assertions should tolerate an optional cost.
  • Our declared ranges permit major-version jumps for cohere and logfire that nothing lock-tests. Worth a look at whether those ranges want upper bounds.

Generated with Claude Code

https://claude.ai/code/session_01E2vP6G2QaFiPBkfY2vQBW8