Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions tests/test_refresh_discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
from citeforge.refresh.types import GenerationSpec, TaskDisposition

NOW = datetime(2026, 8, 12, 12, tzinfo=timezone.utc)
# RefreshEngine.run compares the bound discovery epoch against its own
# wall clock, so a literal month here is a time bomb that detonates in the
# next calendar month. Derive it exactly as citeforge/refresh/engine.py does.
CURRENT_EPOCH = datetime.now(timezone.utc).strftime("%Y-%m")
_GIT = shutil.which("git") or "git"


Expand Down Expand Up @@ -94,7 +98,7 @@ def _real_corpus_authority(

def _policy(*, max_scholar_pages: int = 10, max_html_probe_waves: int = 8) -> DiscoveryPolicy:
return DiscoveryPolicy(
freshness_epoch="2026-08",
freshness_epoch=CURRENT_EPOCH,
adapter_versions={
"arxiv": "1",
"crossref": "1",
Expand Down Expand Up @@ -215,7 +219,7 @@ def test_known_doi_wave_adopts_exact_task5b_csl_identity() -> None:
{"doi": "10.1234/existing"},
("metadata",),
"1",
"2026-08",
CURRENT_EPOCH,
"doi",
)
existing = TaskSpec("author-ada", "pub-one", "doi_csl", "csl_lookup", existing_request)
Expand Down Expand Up @@ -888,7 +892,7 @@ def send_once(_operation: SendOperation) -> requests.Response:
ledger.bind_discovery_policy(policy, DiscoveryCredentials())
result = RefreshEngine(
ledger,
InventoryPolicy(2020, 1000, 10, s2_adapter_version="2", freshness_epoch="2026-08"),
InventoryPolicy(2020, 1000, 10, s2_adapter_version="2", freshness_epoch=CURRENT_EPOCH),
LedgerTransport(ledger, send_once=send_once),
).run(spec, RefreshCredentials(serpapi_key="wire-only"), lambda: False)
assert result.status.value == "continuation", result.detail
Expand Down Expand Up @@ -955,7 +959,7 @@ def send_once(_operation: SendOperation) -> requests.Response:
ledger.bind_discovery_policy(policy, credentials)
result = RefreshEngine(
ledger,
InventoryPolicy(2020, 1000, 10, s2_adapter_version="2", freshness_epoch="2026-08"),
InventoryPolicy(2020, 1000, 10, s2_adapter_version="2", freshness_epoch=CURRENT_EPOCH),
LedgerTransport(ledger, send_once=send_once),
).run(spec, RefreshCredentials(serpapi_key="wire-only"), lambda: False)
assert result.status.value == "continuation"
Expand Down Expand Up @@ -1165,7 +1169,7 @@ def send_empty(_operation: SendOperation) -> requests.Response:
ledger.bind_discovery_policy(policy, DiscoveryCredentials())
result = RefreshEngine(
ledger,
InventoryPolicy(2020, 1000, 10, s2_adapter_version="2", freshness_epoch="2026-08"),
InventoryPolicy(2020, 1000, 10, s2_adapter_version="2", freshness_epoch=CURRENT_EPOCH),
LedgerTransport(ledger, send_once=send_empty),
).run(spec, RefreshCredentials(serpapi_key="wire-only"), lambda: False)
assert result.status.value == "continuation"
Expand Down Expand Up @@ -1304,7 +1308,7 @@ def send_empty(_operation: SendOperation) -> requests.Response:
ledger.bind_discovery_policy(policy, DiscoveryCredentials(s2_key="wire-only"))
result = RefreshEngine(
ledger,
InventoryPolicy(2020, 1000, 10, s2_adapter_version="2", freshness_epoch="2026-08"),
InventoryPolicy(2020, 1000, 10, s2_adapter_version="2", freshness_epoch=CURRENT_EPOCH),
LedgerTransport(ledger, send_once=send_empty),
).run(spec, RefreshCredentials(serpapi_key="wire-only"), lambda: False)
assert result.status.value == "continuation"
Expand Down
44 changes: 40 additions & 4 deletions tests/test_refresh_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import hashlib
import json
import re
import shutil
import subprocess
from dataclasses import replace
Expand All @@ -26,6 +27,13 @@
from citeforge.refresh.transport import LedgerTransport, SendOperation
from citeforge.refresh.types import GenerationSpec, GenerationState, RunStatus, TaskDisposition

# RefreshEngine.run compares the bound discovery epoch against its own
# wall clock, so a literal month here is a time bomb that detonates in the
# next calendar month. Derive it exactly as citeforge/refresh/engine.py does.
CURRENT_EPOCH = datetime.now(timezone.utc).strftime("%Y-%m")
# A month the engine can never consider current, for the staleness guard.
STALE_EPOCH = (datetime.now(timezone.utc).replace(day=1) - timedelta(days=1)).strftime("%Y-%m")


def _spec() -> GenerationSpec:
census = AuthorCensus(
Expand Down Expand Up @@ -438,7 +446,7 @@ def send_once(_operation: SendOperation) -> requests.Response:
"serply": "1",
}
policy = DiscoveryPolicy(
"2026-08",
CURRENT_EPOCH,
adapters,
{
"arxiv": 10,
Expand Down Expand Up @@ -466,7 +474,7 @@ def send_once(_operation: SendOperation) -> requests.Response:
with Ledger.open(tmp_path / "ledger.db") as ledger:
result = RefreshEngine(
ledger,
InventoryPolicy(2020, 1000, 10, s2_adapter_version="2", freshness_epoch="2026-08"),
InventoryPolicy(2020, 1000, 10, s2_adapter_version="2", freshness_epoch=CURRENT_EPOCH),
LedgerTransport(ledger, send_once=send_once),
).run(
full_spec,
Expand All @@ -476,6 +484,7 @@ def send_once(_operation: SendOperation) -> requests.Response:
discovery_credentials=DiscoveryCredentials(),
)
assert result.status is RunStatus.INVALID_CONFIGURATION
assert result.detail == "required s2 discovery credential is unavailable"
assert calls == 0
assert ledger.manifest().data["tasks"] == []

Expand All @@ -497,7 +506,7 @@ def test_generation_start_rejects_stale_discovery_epoch_before_binding(tmp_path:
}
spec = GenerationSpec(base.census, base.refresh_policy_version, {**adapters, "scholar": "1"}, base.base_commit)
policy = DiscoveryPolicy(
"2026-07",
STALE_EPOCH,
adapters,
{
"arxiv": 10,
Expand All @@ -519,7 +528,7 @@ def test_generation_start_rejects_stale_discovery_epoch_before_binding(tmp_path:
with Ledger.open(tmp_path / "ledger.db") as ledger:
result = RefreshEngine(
ledger,
InventoryPolicy(2020, 1000, 10, s2_adapter_version="2", freshness_epoch="2026-08"),
InventoryPolicy(2020, 1000, 10, s2_adapter_version="2", freshness_epoch=CURRENT_EPOCH),
).run(
spec,
RefreshCredentials(serpapi_key="inventory-secret"),
Expand All @@ -528,6 +537,7 @@ def test_generation_start_rejects_stale_discovery_epoch_before_binding(tmp_path:
discovery_credentials=DiscoveryCredentials(s2_key="wire-only"),
)
assert result.status is RunStatus.INVALID_CONFIGURATION
assert result.detail == "discovery freshness does not match the code-owned inventory epoch"
assert ledger._connection.execute("SELECT COUNT(*) FROM discovery_policy_authority").fetchone()[0] == 0
assert ledger.plan_status().revision == 0

Expand Down Expand Up @@ -1323,3 +1333,29 @@ def test_every_blocked_return_seals_a_checkpoint_first() -> None:
if "_save_checkpoint" not in window and not entry_guard and not inside_blocker:
unsealed.append(lines[index].strip())
assert not unsealed, f"blocked returns with no checkpoint seal above them: {unsealed}"


def test_no_refresh_test_pins_a_literal_freshness_epoch() -> None:
"""No engine-driving test may hardcode the month it was written in.

``RefreshEngine.run`` compares the bound discovery epoch against its own
wall clock, so a literal ``"YYYY-MM"`` in a test that reaches that guard
passes for exactly one calendar month and then fails every run afterwards
on every interpreter at once. On 2026-09-01 four tests in
``test_refresh_discovery.py`` detonated this way and blocked every open
pull request. Epochs are derived from ``datetime.now`` or built as an
explicit relative offset, never written down.
"""
# Double-quoted only. The single-quoted months in test_refresh_corpus.py
# live inside SQL that deliberately writes a mismatching epoch to trip a
# drift guard, and are not policy values the engine compares to its clock.
literal = re.compile(r'"\d{4}-(?:0[1-9]|1[0-2])"')
offenders = []
for path in sorted((Path(__file__).parent).glob("test_refresh_*.py")):
source = path.read_text(encoding="utf-8")
if "RefreshEngine" not in source:
continue
for number, line in enumerate(source.splitlines(), start=1):
if literal.search(line) and "noqa: epoch-literal" not in line:
offenders.append(f"{path.name}:{number}: {line.strip()}")
assert not offenders, "literal freshness epochs in engine-driving tests: " + "; ".join(offenders)