Compare commits

...

1 Commits

Author SHA1 Message Date
d018c769bb fix: add gate file rotation to prevent unbounded directory growth
Some checks failed
Architecture Lint / Linter Tests (pull_request) Successful in 25s
PR Checklist / pr-checklist (pull_request) Failing after 4m17s
Smoke Test / smoke (pull_request) Failing after 18s
Validate Config / YAML Lint (pull_request) Failing after 16s
Validate Config / JSON Validate (pull_request) Successful in 15s
Validate Config / Python Syntax & Import Check (pull_request) Failing after 1m28s
Validate Config / Shell Script Lint (pull_request) Failing after 53s
Validate Config / Cron Syntax Check (pull_request) Successful in 11s
Validate Config / Deploy Script Dry Run (pull_request) Successful in 9s
Validate Config / Playbook Schema Validation (pull_request) Successful in 21s
Architecture Lint / Lint Repository (pull_request) Has been cancelled
Validate Config / Python Test Suite (pull_request) Has been cancelled
Closes #674, closes #628

- Age-based cleanup: deletes files older than 7 days
- Count-based cap: keeps at most 50 historical files
- Always preserves eval_gate_latest.json
- Runs automatically after each evaluate_candidate() call
2026-04-15 03:21:06 +00:00

View File

@@ -33,6 +33,11 @@ from pathlib import Path
from typing import Optional
# ── Gate File Rotation ──────────────────────────────────────────────
GATE_FILE_MAX_AGE_DAYS = 7
GATE_FILE_MAX_COUNT = 50
# ── SOUL.md Constraints ──────────────────────────────────────────────
#
# These are the non-negotiable categories from SOUL.md and the
@@ -240,6 +245,9 @@ def evaluate_candidate(
latest_file = gate_dir / "eval_gate_latest.json"
latest_file.write_text(json.dumps(result, indent=2))
# Rotate old gate files to prevent unbounded growth
_rotate_gate_files(gate_dir)
return result
@@ -249,6 +257,48 @@ def _load_json(path: str | Path) -> dict:
return json.loads(Path(path).read_text())
def _rotate_gate_files(gate_dir: Path) -> None:
"""Clean up old gate files to prevent unbounded directory growth.
- Deletes files older than GATE_FILE_MAX_AGE_DAYS
- Caps total count at GATE_FILE_MAX_COUNT (oldest first)
- Always preserves eval_gate_latest.json
"""
if not gate_dir.exists():
return
latest_name = "eval_gate_latest.json"
cutoff = datetime.now(timezone.utc).timestamp() - (GATE_FILE_MAX_AGE_DAYS * 86400)
gate_files = []
for f in gate_dir.iterdir():
if f.name == latest_name or not f.name.startswith("eval_gate_") or f.suffix != ".json":
continue
try:
mtime = f.stat().st_mtime
except OSError:
continue
gate_files.append((mtime, f))
# Sort oldest first
gate_files.sort(key=lambda x: x[0])
deleted = 0
for mtime, f in gate_files:
should_delete = False
if mtime < cutoff:
should_delete = True
elif len(gate_files) - deleted > GATE_FILE_MAX_COUNT:
should_delete = True
if should_delete:
try:
f.unlink()
deleted += 1
except OSError:
pass
def _find_category_score(
sessions: dict[str, dict],
category: str,