Skip to content

Commit c50e3a4

Browse files
wongkclaude
andauthored
fix(code-review): make override-cache tests independent of wall-clock date (#194)
Three tests pinned an override's asserted_at to a fixed 2026-05-29 timestamp and asserted the override was honored. Once that timestamp aged past the 90-day overrides TTL they began failing with no code change. Derive the timestamp relative to now instead. Renames the existing _stale_cached_at() helper to _iso_days_ago() to match its already-generic docstring, and routes the two override TTL boundary tests through it. Claude-Session: https://claude.ai/code/session_011QjUMmrqfGU4QNXDDRLPrN Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 1370b6a commit c50e3a4

4 files changed

Lines changed: 26 additions & 14 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ All notable changes to the claude-plugins project will be documented in this fil
44

55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Entries are listed newest-first; each plugin section is treated as released when merged to `main`.
66

7+
### code-review v3.7.1
8+
9+
#### Fixed
10+
- Override-cache tests no longer depend on the wall-clock date. Three tests pinned an override's `asserted_at` to a fixed `2026-05-29` timestamp and asserted the override was honored — by `verify-prepare` short-circuiting into `override_hits`, and by the prepare-then-consolidate paths that route an override to `RE_ASSERTED`. Once that fixed timestamp aged past the 90-day `overrides` cache TTL, the overrides were correctly treated as expired and the three tests began failing with no accompanying code change. They now derive `asserted_at` relative to the current time, so they exercise the honored-override path regardless of when the suite runs.
11+
12+
#### Changed
13+
- Test helper `_stale_cached_at()` renamed to `_iso_days_ago()` so the name matches its documented behavior (an ISO-8601 timestamp N days in the past, used for both within-TTL and past-TTL fixtures); all call sites updated, and the two override TTL boundary tests now delegate to it instead of inlining the same `datetime.now(timezone.utc) - timedelta(...)` expression.
14+
715
### code v1.14.10
816

917
#### Added

plugins/code-review/.claude-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "code-review",
33
"description": "Code review plugin",
4-
"version": "3.7.0",
4+
"version": "3.7.1",
55
"author": {
66
"name": "ClosedLoop",
77
"email": "support@closedloop.ai"

plugins/code-review/README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,14 @@ plugins/code-review/
4848
python/code_review_schema.py Canonical Finding + ResultEnvelope schema + validators (PLN-719)
4949
python/test_code_review_schema.py Schema tests + round-trips
5050
python/code_review_helpers.py Deterministic helper CLI (parse-diff, hygiene, partition, route, validate, cache, finalize-result, arbitrate-budget, prepare-run, etc.)
51+
python/config/cli.json Declarative argparse spec the helper CLI builds its subparsers from
52+
python/config/stages.json Declarative stage table backing `prepare-run`'s `run_plan.json` and `run-prefix`
53+
python/signal_taxonomy.json Signal taxonomy loaded by signal extraction; its bytes are hashed into the extraction cache key
54+
python/conftest.py Shared pytest fixtures and finding factories for the co-located tests
5155
python/test_code_review_helpers.py Unit tests for the helper CLI
5256
python/golden_fixture_harness.py Golden fixture harness: replays canonical inputs through helper subcommands and diffs against expected envelopes (PLN-719 Phase 8)
5357
python/test_golden_fixtures.py Pytest driver that runs every fixture under tools/python/fixtures/
54-
python/fixtures/<name>/ Per-fixture directory (config.yaml + inputs/ + expected/); 3 full scenarios + 6 README-stubs for future coverage
58+
python/fixtures/<name>/ Per-fixture directory (config.yaml + inputs/ + expected/); 4 full scenarios + 3 README-stubs for future coverage
5559
python/prefix_golden_harness.py Prefix golden harness + subprocess A/B parity oracle: walks the deterministic prefix against real git fixtures — in-process for golden snapshots, and per-stage-subprocess vs `run-prefix` for byte-equal parity (PLN-1229 Phase 0/1)
5660
python/test_prefix_golden.py Pytest driver for the prefix harness: determinism oracle + golden diff across the prefix_fixtures/ matrix
5761
python/prefix_fixtures/<name>/ Per-fixture directory (expected/ golden snapshots); 7 branch scenarios (standard, fast-path, hygiene-only, empty-diff, cache-hit, since-last-review, coverage-critic)

plugins/code-review/tools/python/test_code_review_helpers.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,11 @@
108108
# A `cached_at` timestamp always within the BHA cache TTL (30 days).
109109
# PLN-719 Phase 7 added sweep-on-read TTL eviction; fixtures that want a hit
110110
# must use a fresh timestamp. Tests that want eviction behavior should use
111-
# an explicitly-stale timestamp via ``_stale_cached_at()``.
111+
# an explicitly-stale timestamp via ``_iso_days_ago()``.
112112
_FRESH_CACHED_AT = datetime.now(timezone.utc).isoformat()
113113

114114

115-
def _stale_cached_at(days_ago: int = 365) -> str:
115+
def _iso_days_ago(days_ago: int = 365) -> str:
116116
"""Return an ISO timestamp ``days_ago`` days in the past (default: 1 year)."""
117117
return (datetime.now(timezone.utc) - timedelta(days=days_ago)).isoformat()
118118

@@ -3385,14 +3385,14 @@ def test_stale_entry_within_ttl_hits(self, tmp_path: Path) -> None:
33853385
from code_review_helpers import _is_entry_fresh, CACHE_NAMESPACE_BHA
33863386

33873387
# 29 days old: under the 30-day BHA TTL.
3388-
entry = {"cached_at": _stale_cached_at(days_ago=29)}
3388+
entry = {"cached_at": _iso_days_ago(days_ago=29)}
33893389
assert _is_entry_fresh(entry, CACHE_NAMESPACE_BHA) is True
33903390

33913391
def test_stale_entry_past_ttl_misses(self, tmp_path: Path) -> None:
33923392
from code_review_helpers import _is_entry_fresh, CACHE_NAMESPACE_BHA
33933393

33943394
# 31 days old: past the 30-day BHA TTL.
3395-
entry = {"cached_at": _stale_cached_at(days_ago=31)}
3395+
entry = {"cached_at": _iso_days_ago(days_ago=31)}
33963396
assert _is_entry_fresh(entry, CACHE_NAMESPACE_BHA) is False
33973397

33983398
def test_missing_cached_at_treated_as_fresh(self, tmp_path: Path) -> None:
@@ -3406,7 +3406,7 @@ def test_missing_cached_at_treated_as_fresh(self, tmp_path: Path) -> None:
34063406
def test_unknown_namespace_skips_ttl_check(self, tmp_path: Path) -> None:
34073407
from code_review_helpers import _is_entry_fresh
34083408

3409-
entry = {"cached_at": _stale_cached_at(days_ago=365 * 10)}
3409+
entry = {"cached_at": _iso_days_ago(days_ago=365 * 10)}
34103410
assert _is_entry_fresh(entry, "future-namespace") is True
34113411

34123412
def test_v1_cache_check_evicts_stale_entry(self, tmp_path: Path) -> None:
@@ -3425,7 +3425,7 @@ def test_v1_cache_check_evicts_stale_entry(self, tmp_path: Path) -> None:
34253425
"prompt_hash": "abc123",
34263426
"patch_hash": patch_hash,
34273427
"findings": [{"file": "a.ts", "line": 1, "issue": "stale"}],
3428-
"cached_at": _stale_cached_at(days_ago=45),
3428+
"cached_at": _iso_days_ago(days_ago=45),
34293429
}
34303430
}
34313431
_write_manifest(cache_dir, manifest)
@@ -3443,7 +3443,7 @@ def test_v2_cache_check_evicts_stale_entry(self, tmp_path: Path) -> None:
34433443
patch_hash = _compute_patch_hash("a.ts", diff_data["patch_lines"]["a.ts"])
34443444
composite = _compute_composite_key("opus", "abc123", patch_hash, "ctx")
34453445

3446-
stale = _stale_cached_at(days_ago=45)
3446+
stale = _iso_days_ago(days_ago=45)
34473447
v2_manifest = {
34483448
"a.ts": {
34493449
composite: {
@@ -10133,7 +10133,7 @@ def test_verify_prepare_short_circuits_on_valid_override(
1013310133
"finding_id": "bha_p0_f0",
1013410134
"file_content_hash": _file_content_hash(cr, "src/x.py", 3),
1013510135
"override": "RE_ASSERT",
10136-
"asserted_at": "2026-05-29T22:00:00+00:00",
10136+
"asserted_at": _iso_days_ago(days_ago=1),
1013710137
})
1013810138
# PR #114 review fix — delegate to the shared helper with an
1013910139
# explicit cr_dir override so the per-test stdout/Namespace dance
@@ -11555,7 +11555,7 @@ def test_prepare_then_consolidate_routes_override_to_verified(
1155511555
"finding_id": "bha_p0_f0",
1155611556
"file_content_hash": _file_content_hash(cr, "src/x.py", 3),
1155711557
"override": "RE_ASSERT",
11558-
"asserted_at": "2026-05-29T22:00:00+00:00",
11558+
"asserted_at": _iso_days_ago(days_ago=1),
1155911559
})
1156011560

1156111561
# Phase 1 — prepare. Should record the fid in override_hits and
@@ -11604,7 +11604,7 @@ def test_prepare_then_consolidate_writes_re_asserted_to_stats(
1160411604
"finding_id": "bha_p0_f0",
1160511605
"file_content_hash": _file_content_hash(cr, "src/x.py", 3),
1160611606
"override": "RE_ASSERT",
11607-
"asserted_at": "2026-05-29T22:00:00+00:00",
11607+
"asserted_at": _iso_days_ago(days_ago=1),
1160811608
})
1160911609

1161011610
_, manifest = _run_verify_prepare(
@@ -11736,7 +11736,7 @@ def test_override_invalidated_when_ttl_expired(
1173611736
self._write_target_file(tmp_path, "src/x.py", "a\nb\nc\nd\ne\n")
1173711737
cache = tmp_path / "cache"
1173811738
cache.mkdir()
11739-
old_ts = (datetime.now(timezone.utc) - timedelta(days=120)).isoformat()
11739+
old_ts = _iso_days_ago(days_ago=120)
1174011740
_write_override(cache, {
1174111741
"finding_id": "bha_p0_f0",
1174211742
"file_content_hash": _file_content_hash(cr, "src/x.py", 3),
@@ -11762,7 +11762,7 @@ def test_override_honored_when_ttl_within_bounds(
1176211762
self._write_target_file(tmp_path, "src/x.py", "a\nb\nc\nd\ne\n")
1176311763
cache = tmp_path / "cache"
1176411764
cache.mkdir()
11765-
recent_ts = (datetime.now(timezone.utc) - timedelta(days=30)).isoformat()
11765+
recent_ts = _iso_days_ago(days_ago=30)
1176611766
_write_override(cache, {
1176711767
"finding_id": "bha_p0_f0",
1176811768
"file_content_hash": _file_content_hash(cr, "src/x.py", 3),

0 commit comments

Comments
 (0)