From 9562bb7cc0dfbf7a43f2f8dd0eb88e64be5b3136 Mon Sep 17 00:00:00 2001 From: Youssef Aitousarrah Date: Fri, 10 Apr 2026 09:56:22 -0700 Subject: [PATCH] fix(hypotheses): id validation, worktree prune, safe loop, 14d enrichment cutoff Co-Authored-By: Claude Sonnet 4.6 --- scripts/compare_hypothesis.py | 2 +- scripts/run_hypothesis_runner.py | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/scripts/compare_hypothesis.py b/scripts/compare_hypothesis.py index ac6a72aa..9415a7f4 100644 --- a/scripts/compare_hypothesis.py +++ b/scripts/compare_hypothesis.py @@ -56,7 +56,7 @@ def compute_7d_return(ticker: str, pick_date: str) -> Tuple[Optional[float], Opt def enrich_picks_with_returns(picks: list) -> list: """Compute 7d return for each pick >= 7 days old that lacks return_7d.""" - cutoff = (datetime.utcnow() - timedelta(days=7)).strftime("%Y-%m-%d") + cutoff = (datetime.utcnow() - timedelta(days=14)).strftime("%Y-%m-%d") for pick in picks: if pick.get("return_7d") is not None: continue diff --git a/scripts/run_hypothesis_runner.py b/scripts/run_hypothesis_runner.py index 6795d0b7..b15c02f6 100644 --- a/scripts/run_hypothesis_runner.py +++ b/scripts/run_hypothesis_runner.py @@ -19,6 +19,7 @@ Environment variables: import json import os +import re import subprocess import sys from datetime import datetime @@ -116,6 +117,10 @@ def save_picks_to_worktree(worktree: str, hypothesis_id: str, scanner: str, pick def run_hypothesis(hyp: dict) -> bool: """Run one hypothesis experiment cycle. Returns True if the experiment concluded.""" hid = hyp["id"] + # Validate id to prevent path traversal in worktree path + if not re.fullmatch(r"[a-zA-Z0-9_\-]+", hid): + print(f" Skipping hypothesis with invalid id: {hid!r}", flush=True) + return False branch = hyp["branch"] scanner = hyp["scanner"] worktree = f"/tmp/hyp-{hid}" @@ -287,8 +292,12 @@ def main(): if not running: print("No running hypotheses to process.", flush=True) else: + run(["git", "worktree", "prune"], check=False) for hyp in running: - run_hypothesis(hyp) + try: + run_hypothesis(hyp) + except Exception as e: + print(f" Error processing {hyp['id']}: {e}", flush=True) promote_pending(registry) save_registry(registry)