Scrub references to older versions
Quality Gate / gate (push) Successful in 2m39s

This commit is contained in:
Jim Lancaster
2026-09-02 17:02:48 -05:00
parent eeb1888aa3
commit 065acad125
20 changed files with 70 additions and 545 deletions
+1 -1
View File
@@ -24,7 +24,7 @@ from transcription.services.workflows import advance_job
async def _attempts_for_job(session, job) -> list[ExecutionAttempt]:
"""Load execution attempts for a job; V4.7 moved evidence off JobSource."""
"""Load execution attempts for a job; evidence lives on ExecutionAttempt."""
job_source_ids = [job_source.id for job_source in job.job_sources]
result = await session.exec(select(ExecutionAttempt).where(col(ExecutionAttempt.job_source_id).in_(job_source_ids)))
return list(result.all())
@@ -1,4 +1,4 @@
"""V4.5 retranscription candidate and promotion tests."""
"""Retranscription candidate and promotion tests."""
from uuid import uuid4
@@ -20,7 +20,7 @@ def _services(default_session_factory, settings: Settings) -> ServiceBundle:
async def _seed_source(services: ServiceBundle) -> Source:
document = await services.documents.create_document(Document(name="V4.5 source"))
document = await services.documents.create_document(Document(name="candidate source"))
source = Source(
document_id=document.id,
page_number=1,
+2 -2
View File
@@ -1,4 +1,4 @@
"""Tests for deterministic V4.5 transcription warnings."""
"""Tests for deterministic transcription warnings."""
import pytest
@@ -8,7 +8,7 @@ from transcription.services.quality import quality_warning_payload
@pytest.mark.unit
def test_quality_analysis_reports_each_v45_warning_without_mutating_text():
def test_quality_analysis_reports_each_quality_warning_without_mutating_text():
text = (
"[document body handwritten]\n"
"[document body typewritten]\n"
@@ -1,4 +1,4 @@
"""Focused V4.2 evidence, integrity, and benchmark tests."""
"""Focused evidence, integrity, and benchmark tests."""
from __future__ import annotations
+47
View File
@@ -69,6 +69,19 @@ _BASELINE_CLAIM = re.compile(
r"\b(?:Current Baseline:\s*|current\s+|active\s+|canonical\s+)V(\d+(?:\.\d+)?)",
re.IGNORECASE,
)
_LEGACY_VERSION_REFERENCE = re.compile(r"\b[Vv](4(?:\.\d+)?|5(?:\.\d+)?|6\.0)\b|test_v42_evidence|test_v45_candidates")
LEGACY_VERSION_REFERENCE_EXCLUSIONS = frozenset(
{
".github/workflows/quality-gate.yml",
"docs/data_migration.md",
"docs/requirements.md",
"docs/reviews",
"docs/roadmap_plan.md",
"docs/schema.md",
"src/transcription/db/operations.py",
"tests/test_meta_contract_guards.py",
}
)
def _declared_baseline() -> str:
@@ -112,6 +125,40 @@ def test_canonical_docs_declare_one_consistent_baseline():
)
def test_legacy_version_markers_are_scoped_to_allowed_historical_files():
"""Version labels from older project baselines should not linger in active files.
Historical references are allowed only where the old version is the subject matter:
roadmap planning, dated reviews, stable requirement IDs, and explicit migration or
compatibility notes.
"""
scanned: list[Path] = []
for root in (
PROJECT_ROOT / ".github",
PROJECT_ROOT / "docs",
PROJECT_ROOT / "src",
PROJECT_ROOT / "tests",
):
scanned.extend(path for path in root.rglob("*") if path.suffix in {".md", ".py", ".yml", ".yaml"})
scanned.extend((PROJECT_ROOT / "AGENTS.md", PROJECT_ROOT / ".pre-commit-config.yaml"))
violations: dict[str, list[str]] = {}
for path in sorted(set(scanned)):
relative = path.relative_to(PROJECT_ROOT).as_posix()
if any(
relative == excluded or relative.startswith(f"{excluded}/")
for excluded in LEGACY_VERSION_REFERENCE_EXCLUSIONS
):
continue
matches = sorted(
{match.group(0) for match in _LEGACY_VERSION_REFERENCE.finditer(path.read_text(encoding="utf-8"))}
)
if matches:
violations[relative] = matches
assert violations == {}, f"Legacy version markers remain in active files: {violations}"
def test_active_contract_files_are_present():
"""Guard the guard: ensure all expected authority files are scanned."""
missing = [path for path in ACTIVE_CONTRACT_FILES if not (PROJECT_ROOT / path).exists()]
+1 -1
View File
@@ -232,7 +232,7 @@ class TestPersonAndDocumentPersonModel:
class TestJobSourceModel:
def test_job_source_is_a_queue_row_not_an_evidence_row(self, session):
"""V4.7: job_source carries only queue state; evidence lives on execution_attempt."""
"""job_source carries only queue state; evidence lives on execution_attempt."""
document = _persist_document(session)
job = _persist_job(session, document)
source = _persist_source(session, document)
+1 -1
View File
@@ -142,7 +142,7 @@ async def seed_job(app_client: tuple[FastAPI, TestClient]) -> Callable[..., Awai
session.add(job_source)
await session.flush()
# V4.7: evidence lives on execution_attempt, not job_source.
# Evidence lives on execution_attempt, not job_source.
executed_at = datetime.now(UTC)
session.add(
ExecutionAttempt(
+1 -1
View File
@@ -357,7 +357,7 @@ class TestSourcesPageRendering:
await service.update_job_source_transcription(
job_id=job_id,
source_id=source_id,
text="V4.2 transcription",
text="Machine transcription",
raw_api_response={"id": "sdk-snapshot"},
ai_metadata={"finish_reason": "stop"},
provider="openrouter",