Orchestrata Ultimate › Gates › freshness-guard

Gate: freshness-guard

At a glance

Purpose "Detect and refresh every stale-data class the 2026-08-04 run history hit (Mohamed ruling: 'no staleness, every run is fresh')" — module docstring of scripts/freshness_guard.py.
Where it runs scripts/run_tests.py::_main, step 0, before basetemp pruning, affected resolution, infra and the safety gates. So it runs inside the pre-push hook and inside deploy/ship.sh's verify, which both call run_tests.py.
Trigger Every run_tests.py invocation unless --skip-freshness is passed. A tree with no scripts/freshness_guard.py prints ⚠ freshness_guard.py not found — skipping freshness guard.
Exact command python scripts/freshness_guard.py (detect and refresh) · python scripts/freshness_guard.py --check (detect only). The runner calls it as [sys.executable, scripts/freshness_guard.py] with timeout=900.
Blocks Refresh mode: exit 1 when a refresh failed → run_tests.py returns _abort("freshness"). --check: exit 1 when anything is stale.
Ruling / ADR The 2026-08-04 ruling quoted in the docstring and in run_tests.py step 0. No RUL page names this script (rulings Enforcement lists, 2026-10-23).

What it checks

Six checks, run in this order (CHECKS in scripts/freshness_guard.py, read with the AST toolkit). Each is a (detect, refresh) pair and returns (stale, ok).

# Output name Detects Refreshes Founding incident (docstring)
1 ast-runtime-merge plans/ast-ultimate.json has zero runtime_calls entries while plans/runtime-callgraph.json exists build_runtime_callgraph.py reaugment in place A bare ast-sync dropped every runtime_calls field; derive_rtm fell 1055 → 575
2 prolog-kbs trace_intel's STRUCTURAL_FACTS / TRACEABILITY_FACTS or .claude/run/codebase_kb/facts.pl missing or older than the snapshot's mtime trace_intel.ensure_kb(no_refresh=False), then scripts/code_intel.py reindex (timeout 600 s) only when the code_intel KB was stale Stale structural facts made derive_rtm abort
3 durations-sink A record in reports/test-durations.ndjson older than 7 days or naming a deleted test file Compact in place The sink grew to 267 MB / 1.78M lines; ~4.4 s per runner start
4 observer-registry A $XDG_RUNTIME_DIR/orchestrata/pytest-sessions/*.json with status=running whose pid is dead Mark it status=killed ("never faked to finished") "11 running" with zero live pids
5 packer-cache .cache/test_durations.json keys for modules that no longer exist Drop them Dead entries skewed bin packing
6 runtime-capture plans/runtime-callgraph.json older than 7 days Report only — schedule an instrumented run with a per-batch ORCH_RCG_DIR, never a global PYTEST_ADDOPTS A global PYTEST_ADDOPTS leaked into nested pytest and broke 6 modules on 2026-08-04

Real output, from the passing push of 2026-10-22 (push-item3-retry3.log lines 7–12):

[freshness] ast-runtime-merge: FRESH — runtime_calls present
[freshness] prolog-kbs: FRESH — all KBs newer than snapshot
[freshness] durations-sink: FRESH — 714 records, all current
[freshness] observer-registry: FRESH — no dead-pid running sessions
[freshness] packer-cache: FRESH — 9 entries, all current
[freshness] runtime-capture: FRESH — 0.2 days old

Other statuses the checks print: STALE, REFRESHED, REFRESH-FAILED, SKIP (for example prolog-kbs: SKIP no snapshot).

Diagram projects-orchestrata-ultimate-gates-freshness-guard-1

Why a run can spend minutes here

Check 2 delegates to scripts/trace_intel.py::ensure_kb, which (read with the AST toolkit) re-runs extract when the traceability facts are stale, calls _refresh_snapshot (runs REPO_ROOT/.venv/bin/ast-sync --output-dir .cache/ast when the source tree is newer than the live snapshot; its docstring measured "~12s warm"), and reindexes the structural KB from the active snapshot (.cache/ast/… when present, else plans/ast-ultimate.json).

The coordinator's notes of 2026-10-22 record a "run_tests.py trace_intel preflight" of 180–234 s after any edit, which killed every 300 s VERIFY that day. run_tests.py itself has no trace_intel reference (AST source of the module); freshness_guard.py:153 is a call site of ensure_kb. So that preflight cost is this guard's check 2. The split of the 180–234 s between extract, ast-sync and reindex is not measured.

Known gap

IMPROVEMENT-LOG finding F3 (2026-10-22): run_tests.py --affected resolves import closures from plans/ast-ultimate.json, and after the commit discipline restored that file to its committed version (which lacked core/threading/failure_detail.py) the run refused, "and the runner's freshness guard refreshed the Prolog KBs without noticing the snapshot is missing a src/ file". That matches the code: check 2 compares KB mtimes with the snapshot's mtime; none of the six checks compares the committed snapshot's module set with the source tree.

Typical failures and how to fix them

Symptom Cause Fix
Run aborts at stage freshness A refresh step exited non-zero (for example prolog-kbs: REFRESH-FAILED <stderr tail> from code_intel.py reindex) Run python scripts/freshness_guard.py alone and read the failing line; fix that artifact's generator
A 300 s VERIFY budget is gone before tests start Check 2 rebuilding the trace_intel KBs after an edit (above) Warm the KBs before a timed run (run the guard once), or budget for it in the brief, as better-briefs memory records
runtime-capture: STALE Capture older than 7 days Report only; schedule an instrumented suite run. Not a failure
--affected refuses "outside the serialized import closure" although the guard printed FRESH F3: the snapshot lacks a new src/ file Re-serialize the snapshot before the run; do not restore plans/ast-ultimate.json between measuring and running (D14 in the IMPROVEMENT-LOG)