Skip to content

test(fixtures): stop stamping a clock into the uv archive fixture - #2001

Open
seonghobae wants to merge 3 commits into
mainfrom
fix/deterministic-uv-archive-fixture
Open

test(fixtures): stop stamping a clock into the uv archive fixture#2001
seonghobae wants to merge 3 commits into
mainfrom
fix/deterministic-uv-archive-fixture

Conversation

@seonghobae

@seonghobae seonghobae commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

What was broken

_trusted_uv_archive is documented as building "a deterministic uv tar archive". It was not:
tarfile.open(mode="w:gz") writes the current time into the gzip header. The docstring was
false, which is why nobody looked.

Its bytes feed a pytest.mark.parametrize value directly, so pytest derives three test ids from
them. Collecting the same tree twice produced 4 differing lines — 2 ids "disappeared" and 2
"appeared"
:

test_verified_uv_binary_rejects_invalid_archives[\x1f\x8b\x08\x00\xbb\xf6\x9dj...]
                                                 \x1f\x8b\x08\x00\xcc\xf6\x9dj...
                                                              ^^^^^^^^ gzip MTIME

Why it matters beyond one file

Diffing collected test ids between two commits is how a conflict resolution is checked for silently
dropped assertions — deleting an assertion makes tests pass, so no gate can see the loss. A peer
session applying that technique across two heads of #1986 read these two unstable ids as "2 tests
vanished"
and was about to attribute the loss to that PR. A control — collecting the same tree
twice — is what caught it. The rule was sound; the instrument was not.

The defect is on main, not on #1986. Reproduced independently here on a main-derived branch.

TarInfo.mtime already defaults to 0, so the gzip header was the only clock left.

The test asserts the field, not the repetition — and that matters

The obvious regression test is:

assert _trusted_uv_archive(**kw) == _trusted_uv_archive(**kw)

It passes against the unfixed helper. gzip MTIME has one-second resolution, so two back-to-back
builds agree; it only fails when the pair straddles a second boundary. I wrote that version first
and the mutation control is what exposed it — not review, because it reads correct. The form that
works asserts the header field directly:

assert _trusted_uv_archive(**kw)[4:8] == b"\x00\x00\x00\x00"

Correction — that fix was not in the first pushed head, and this section previously claimed it
was.
af5c50e7 shipped the production mtime=0 change together with the vacuous test. The
mutation control that exposed the vacuity ends by restoring the file with git restore, which makes
the working tree match the commit, not my edit; the --amend that followed therefore captured
the reverted test. A peer caught it and pushed 10192de7 with the same field assertion this
paragraph describes, verified here as load-bearing: it passes on the current head and fails when the
clock is put back.

The process lesson outlasts the bug. On later work in this session I started committing before
mutating for exactly this reason — but I applied that forward only and never checked what the
earlier ordering had already damaged. When you find a process fault, audit what it has already
produced, not just what it might produce next.

A peer's version of the same control did catch the original bug, because they collected the whole
test tree twice and a full collection takes seconds. Same idea, different sampling interval,
opposite discriminating power — and neither of us chose that interval deliberately.

Verification

tests/test_materialize_base_python_requirements.py   49 passed
control: two collections of the same tree            4 differing ids -> 0
mutation: restore the clock                          test_trusted_uv_archive_carries_no_clock FAILED

Full gate, run through this machine's new voluntary suite lock:

2976 passed, 1 skipped, 21 subtests passed in 1261.36s
TOTAL 13194 stmts 0 miss 5330 branch 0 partial  100%
interrogate RESULT: PASSED (minimum: 100.0%, actual: 100.0%)

Predicted 2976 before running (2975 on main + 1 new); matched exactly.

Do not read 1261s as a timing measurement. The lock is voluntary and no other session was
using it yet, so three unrelated test processes ran alongside this one at load average ~50 on 10
cores. Holding the lock is not the same as having the machine. The pass/fail and coverage numbers
are unaffected by contention — separate worktrees keep separate .coverage — and are the only
figures cited here.

Developer experience: an id-set diff between two commits now measures the tests instead of the
clock, so the check for a conflict resolution that quietly dropped an assertion stops reporting
losses that never happened.

User experience: no user-visible change; this is test-fixture hygiene.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • 테스트
    • 아카이브 생성 결과가 실행 시점에 관계없이 일관되도록 검증을 강화했습니다.
    • 기본 구성, 이름이 변경된 항목, 디렉터리 항목을 포함한 다양한 경우에 타임스탬프 정보가 포함되지 않는지 확인합니다.

``_trusted_uv_archive`` is documented as building "a deterministic uv tar
archive", but ``tarfile.open(mode="w:gz")`` writes the *current* time into the
gzip header, so it was not. Its bytes feed a ``pytest.mark.parametrize`` value
directly, so pytest derives three test ids from them, and two of the three
changed on every collection:

    test_verified_uv_binary_rejects_invalid_archives[\x1f\x8b\x08\x00\xbb\xf6\x9dj...]
                                                     \x1f\x8b\x08\x00\xcc\xf6\x9dj...

Bytes 4:8 there are the gzip MTIME field. Collecting the same tree twice
produced 4 differing lines: 2 ids "disappeared" and 2 "appeared".

That breaks a technique this repository relies on. Diffing collected test ids
between two commits is how a conflict resolution is checked for silently
dropped assertions -- deleting an assertion makes tests pass, so no gate can
see the loss. A peer session applying it across two heads of #1986 read those
two unstable ids as "2 tests vanished"; a control run of the same tree twice is
what caught it. The rule was sound and the instrument was not.

``TarInfo.mtime`` already defaults to 0, so the gzip header was the only clock
left, and writing that layer explicitly with ``mtime=0`` makes the helper match
its own docstring.

The accompanying test asserts the MTIME header field is zero rather than
building the archive twice and comparing. The build-twice version is the
obvious check and it is vacuous: gzip MTIME has one-second resolution, so two
back-to-back builds agree even with the clock restored. It was written that way
first and passed against the unfixed helper -- the mutation control is what
exposed it, not review.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 7, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 4f8e9398-b8c8-46ba-8eb0-750dc88bfb08

📥 Commits

Reviewing files that changed from the base of the PR and between 78a4937 and d46f4f1.

📒 Files selected for processing (1)
  • tests/test_materialize_base_python_requirements.py

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

_trusted_uv_archive가 gzip 헤더의 MTIME을 0으로 설정하도록 변경되었습니다. 기본 멤버, 이름 변경 멤버, 디렉터리 멤버에서 해당 값이 0인지 검증하는 테스트가 추가되었습니다.

Changes

아카이브 결정성

Layer / File(s) Summary
결정적 gzip 아카이브 생성 및 검증
tests/test_materialize_base_python_requirements.py
_trusted_uv_archivegzip.GzipFilemtime=0을 사용합니다. 새 테스트가 세 가지 아카이브 변형의 gzip MTIME 필드를 검증합니다.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to d46f4

Test archive output is now stable across runs, preventing clock-dependent fixture bytes and test identifiers without changing user-visible behavior.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 _trusted_uv_archive 테스트 픽스처에서 시간 기록을 제거하는 주요 변경 사항을 정확하고 간결하게 설명합니다.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 1 files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/deterministic-uv-archive-fixture

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@seonghobae seonghobae added maintenance priority: medium Normal-priority or P2 work type: maintenance Maintenance, build, dependency, or operational upkeep labels Sep 7, 2026 — with ChatGPT Codex Connector
@seonghobae
seonghobae marked this pull request as draft September 7, 2026 02:00

@seonghobae seonghobae left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Exact-head review for af5c50e72f4e661b8f408f34593ec9dd89d44e94.

Blocking regression-contract mismatch: the PR body correctly explains that back-to-back equality is non-discriminating because gzip MTIME has one-second resolution, and says the shipped test directly asserts archive[4:8] == b"\x00\x00\x00\x00". The actual source does not contain that assertion. test_trusted_uv_archive_bytes_are_stable_across_builds() still compares two immediately consecutive builds, so the pre-fix tarfile.open(mode="w:gz") implementation can pass whenever both calls occur in the same second. This does not prove the causal clock field and can miss the exact regression it is intended to lock.

Please make the production assertion match the documented/mutation-proven contract by checking the gzip header MTIME bytes for all three archive shapes (or an equivalently deterministic injected-clock test), then re-run the focused mutation control and exact-head hosted gate. The gzip.GzipFile(..., mtime=0) implementation itself is appropriately minimal; the finding is limited to the regression test/evidence mismatch. This review is not approval or protected-merge evidence.

@seonghobae seonghobae left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Exact-head revalidation for 10192de781f4c986b6455d408aa1aad2fcbbafdb: the regression-contract mismatch from review 5127434582 is resolved. The test now directly asserts gzip header MTIME bytes [4:8] == 00000000 for the normal, wrong-member, and directory archive shapes; the non-discriminating immediate-equality assertion is gone. A fresh isolated mutation control executed the exact stdlib construction pattern: fixed header 00000000, legacy tarfile.open(mode="w:gz") header nonzero, exit 0. This is bounded causal evidence only; the new exact-head hosted workflow 34074974465 and review/security gates remain non-terminal and must not be represented as GREEN. Ready is review admission, not approval or merge authority.

@seonghobae
seonghobae marked this pull request as ready for review September 7, 2026 02:05
@seonghobae
seonghobae enabled auto-merge (squash) September 7, 2026 02:06
@opencode-agent
opencode-agent Bot disabled auto-merge September 7, 2026 03:35
@seonghobae
seonghobae enabled auto-merge (squash) September 7, 2026 03:59
@opencode-agent
opencode-agent Bot disabled auto-merge September 7, 2026 05:26

@cwl-noema-review cwl-noema-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Noema LLM review

The change replaces tarfile.open(mode='w:gz') with an explicit gzip.GzipFile(fileobj=payload, mode='wb', mtime=0) wrapping tarfile.open(mode='w'), pinning the gzip header MTIME to zero. This makes the _trusted_uv_archive fixture fully deterministic, preventing phantom test-id drift across collection runs. A new test (test_trusted_uv_archive_carries_no_clock) verifies bytes 4-8 (MTIME field) are zero for all three helper variants. No correctness, security, or maintainability issues were found.

Reviewed changed lines

  • tests/test_materialize_base_python_requirements.py:723 (RIGHT): Wraps the tar writer with an explicit gzip.GzipFile(mtime=0). This pins the gzip header MTIME to zero while preserving the tar stream structure, and nested context managers ensure the tar end-of-archive blocks are written and the gzip footer is finalized. Existing archive-consumption tests still pass.
  • tests/test_materialize_base_python_requirements.py:828 (RIGHT): The new test iterates over all three helper configurations (default, alternate member_name, directory member). Since the gzip layer is identical regardless of these parameters, the test validates MTIME=0 across every code path that calls the helper.
  • tests/test_materialize_base_python_requirements.py:829 (RIGHT): Asserts bytes 4-8 of the gzip output equal b'\x00\x00\x00\x00'. Per RFC 1952, these bytes are exactly the MTIME field in the mandatory 10-byte header, independent of optional fields. The assertion is sound and directly verifies determinism.

Adversarial validation

  • tests/test_materialize_base_python_requirements.py:723 (RIGHT) falsified: Explicit gzip.GzipFile may lack an exit that closes tarfile before it finishes writing the tar end-of-archive blocks, producing truncated archives. — tarfile.open(mode='w') writes the two end-of-archive blocks and closes the fileobj on exit, then the gzip.GzipFile context manager finalizes the gzip stream. Existing helper call sites and downstream decompression tests validate the returned bytes, so archive integrity is preserved.
  • tests/test_materialize_base_python_requirements.py:828 (RIGHT) falsified: The new test may not cover the actual archive variant consumed by supply-chain tests, so deterministic IDs could regress for the used variant while this test still passes. — gzip.GzipFile(mtime=0) is applied at the outer layer of every helper invocation, independent of member_name or regular. The loop's three variants (default, alternate member name, directory member) exercise every branch that alters tar contents while still validating MTIME=0 for each, covering all helper paths.
  • tests/test_materialize_base_python_requirements.py:829 (RIGHT) falsified: The test fixed byte slice [4:8] may not correspond to MTIME when gzip FLG enables optional fields, so assertion could false-positive with a non-deterministic header. — gzip.GzipFile writes the mandatory 10-byte header: magic 0x1f8b, CM=8, FLG=0, MTIME=0. Bytes [4:8] are exactly MTIME and FLG=0 means no optional fields are present, so the assertion directly verifies zero MTIME in all cases.
  • Residual risk: No material residual risk. The change is isolated to the test helper and its new determinism test; no production code or security boundaries are affected.

Findings

  • No blocking findings.
  • Result: APPROVE
  • Head SHA: 10192de781f4c986b6455d408aa1aad2fcbbafdb
  • Reviewer credential: noema-review-github-app-refresh
  • Actor: cwl-noema-review[bot]

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

OpenCode could not approve from deterministic current-head evidence because GitHub Checks have failed.

Findings

1. HIGH Current-head GitHub Checks - Fix failed required checks before approval

  • Problem: Failed same-head checks remain for d46f4f1a634db6836b8b5b90bdd26caf16cbdc1d.
  • Root cause: The model-unavailable evidence fallback is allowed only when peer GitHub Checks are complete and clean.
  • Fix: Read and fix the failed check logs below, then rerun the current-head checks.
  • Regression test: Keep the model-unavailable fallback gated on an empty failed-check rollup.

Failed checks:

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Test: test_materialize_base_python_requirements.py"]
  S1 --> I1["regression suite"]
  I1 --> R1["Review risk: Test: test_materialize_base_python_requirements.py"]
  R1 --> V1["targeted test run"]
Loading

@opencode-agent

opencode-agent Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

OpenCode Review Overview

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintenance priority: medium Normal-priority or P2 work type: maintenance Maintenance, build, dependency, or operational upkeep

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant