Skip to content

test(manager): keep the evidence-window fixture off the UTC date rollover - #4612

Merged
huangruiteng merged 1 commit into
mainfrom
codex/manager-evidence-window-fixture-20260917
Sep 17, 2026
Merged

huangruiteng merged 1 commit into
mainfrom
codex/manager-evidence-window-fixture-20260917

Conversation

@huangruiteng

Copy link
Copy Markdown
Collaborator

What changed

tests/test_chat_manager_context.py::test_turn_context_reads_a_bounded_window_and_declares_sources builds six days of receipts from datetime.now(timezone.utc) minus (days_ago, minutes=index). Twelve minute offsets push the oldest row past its own UTC date whenever the suite runs between 00:00 and 00:11 UTC, so the six-day fixture spans seven calendar dates. A correct seven-day window then reports seven day buckets, and assert len(window["matched_by_day"]) == 6 fails.

This PR anchors the newest fixture receipt to 18:00 UTC on the previous UTC day. Every row stays in the past, and every row sits at least eleven minutes inside its own UTC date, so the row set is date-stable at any wall-clock time and still exercises the per-day limit, the total limit, and the fully readable newest receipt.

Evidence

Failing required check on an unrelated PR (no test file touched by it):

gh api .../actions/jobs/105021863085/logs
tests/test_chat_manager_context.py:149: AssertionError: assert 7 == 6
E  where 7 = len({'2026-09-17': 6, '2026-09-16': 12, '2026-09-15': 12, '2026-09-14': 12, ...})
# job timestamp 2026-09-17T00:08:46Z

The real reader called with an injected clock inside that window (now = 2026-09-17T00:05:46Z, lookback_days=7, limit=8, total_limit=48):

Fixture day buckets matched included newest receipt
wall-clock anchor (before) 7 72 48 2026-09-17T00:05:46+00:00
fixed date-stable anchor (after) 6 72 48 2026-09-16T18:00:00+00:00

The product window is unchanged: all 72 rows stay inside the seven-day window and inside the past, and the same 48 receipts are included. Only the fixture's day span becomes deterministic. A sweep of every minute across three days (4320 samples) reports 7 buckets for 33 minutes with the old anchor and 6 buckets for all samples with the new one.

Validation

cd <worktree> && TZ=UTC uv run --extra test python -m pytest \
  tests/test_chat_manager_context.py tests/test_chat_manager_details.py \
  tests/test_chat_manager_report.py -q
# 30 passed

.venv/bin/python -m ruff check tests/test_chat_manager_context.py
# All checks passed!

ruff format --check reports four pre-existing hunks in this file (for example _write_delivery_index) that this PR leaves untouched; the changed lines are format-clean.

Boundary

Test-only, single-purpose, reversible: one fixture anchor in one test file, no product code, runtime, control-plane, permission, scoring, or public-surface change. No credentials, private state, raw evidence, or local paths. The file is also touched by #4593, but in an unrelated hunk.

…over

`test_turn_context_reads_a_bounded_window_and_declares_sources` built six
days of receipts at `datetime.now(timezone.utc)` minus `(days_ago, minutes=index)`.
When the shard runs between 00:00 and 00:11 UTC the oldest row lands on a
seventh UTC date, so a correct 7-day window reports seven day buckets and the
assertion `len(matched_by_day) == 6` fails. PR #4591's test-shard (1) failed
exactly that way at 2026-09-17T00:08:46Z.

Anchor the newest receipt to 18:00 UTC on the previous UTC day, which keeps
every row in the past and at least eleven minutes inside its own UTC date, so
the fixture exercises the per-day and total bounds instead of the wall clock.

Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

动机

tests/test_chat_manager_context.py::test_turn_context_reads_a_bounded_window_and_declares_sources 用挂钟时间构造六天回执:datetime.now(timezone.utc) - timedelta(days=days_ago, minutes=index)。当测试运行在 00:00–00:11 UTC 之间时,最早的几条回执会跨到当天 UTC 日期之前,六天的 fixture 实际横跨七个日历日,于是正确的 7 天窗口返回七个 day bucket,assert len(window["matched_by_day"]) == 6 失败。PR #4591 的 test-shard (1)(job 105021863085,2026-09-17T00:08:46Z)正是这样红的:AssertionError: assert 7 == 6,bucket 为 {'2026-09-17': 6, '2026-09-16': 12, ...}。这是每天固定出现 11 分钟的必现窗口,不是随机 flake,且拦的是与本 PR 无关的改动。

改动思路

断言本身没错,错的是 fixture 让「六天」依赖挂钟。不放松断言、不改产品代码,只把 fixture 的锚点固定在「前一天 18:00 UTC」:所有回执都在过去,且每条都距离自己 UTC 日期边界至少 11 分钟,因此无论测试在当天什么时刻运行,day bucket 恒为 6。

具体改动

新增 newest = (now - timedelta(days=1)).replace(hour=18, minute=0, second=0, microsecond=0),回执改为 newest - timedelta(days=days_ago, minutes=index),并补上说明为何不能用挂钟锚点的注释。产品侧 read_manager_delivery_history 未改。

对主干的风险

仅测试 fixture,单文件、可回滚,不改产品、运行时、控制面、权限与公开面。用注入时钟(now = 2026-09-17T00:05:46Z,lookback_days=7、limit=8、total_limit=48)直接调用真实读取器核对:旧锚点 buckets=7 matched=72 included=48,新锚点 buckets=6 matched=72 included=48,窗口内命中与总限额行为不变。三分种逐分钟抽样(4320 个采样)旧锚点有 33 分钟为 7 bucket,新锚点恒为 6。本地 pytest tests/test_chat_manager_context.py tests/test_chat_manager_details.py tests/test_chat_manager_report.py -q 30 passed;ruff check 通过。同一文件也被 #4593 修改,但位于无关 hunk。

我的整体评价

修复的是必现的测试脆弱点,证据链完整(CI 日志 + 注入时钟的真实读取器对比 + 4320 点抽样),改动面最小且不放松任何断言。建议在该 head 的 required checks 变绿后合并。

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

Head: 962db4495b8e0bf99a9be8480dc85f6f6dc78feb

English verdict: APPROVE

@huangruiteng
huangruiteng merged commit 6b3264f into main Sep 17, 2026
23 checks passed
@huangruiteng
huangruiteng deleted the codex/manager-evidence-window-fixture-20260917 branch September 17, 2026 00:49
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.

1 participant