1313import subprocess
1414import sys
1515import tempfile
16- from datetime import datetime , date , timedelta
16+ from datetime import date , datetime , timedelta
1717from pathlib import Path
1818
1919sys .path .insert (0 , str (Path (__file__ ).parent .parent ))
@@ -209,7 +209,7 @@ def _files_in_cooling_period() -> set[str]:
209209 cooling .add (f )
210210 except (ValueError , TypeError ):
211211 # Fail safe: treat unparseable as within cooling period
212- print (f " WARNING: Could not parse timestamp for deployed change — treating as in cooling period" )
212+ print (" WARNING: Could not parse timestamp for deployed change — treating as in cooling period" )
213213 for f in change .get ("files_modified" , []):
214214 cooling .add (f )
215215 return cooling
@@ -335,7 +335,7 @@ def read_performance_summary() -> dict:
335335
336336def read_positions () -> dict :
337337 """Read current open positions from Alpaca API.
338-
338+
339339 Returns dict with positions list and account summary.
340340 """
341341 try :
@@ -372,7 +372,7 @@ def read_positions() -> dict:
372372
373373def read_code (file_path : str ) -> dict :
374374 """Read a file from the repo.
375-
375+
376376 Returns dict with content or error. Validates path is within project.
377377 """
378378 try :
@@ -403,10 +403,10 @@ def read_experiment_results() -> dict:
403403 experiments .append (json .loads (f .read_text ()))
404404 except Exception as e :
405405 experiments .append ({"file" : f .name , "error" : str (e )})
406-
406+
407407 active = [e for e in experiments if e .get ("status" ) == "active" ]
408408 completed = [e for e in experiments if e .get ("status" ) in ("promoted" , "discarded" , "expired" )]
409-
409+
410410 return {
411411 "total" : len (experiments ),
412412 "active" : len (active ),
@@ -685,11 +685,9 @@ def compute_measured_impact(change_id: str) -> dict:
685685
686686 # Find the changelog entry
687687 entry = None
688- entry_idx = None
689688 for i , change in enumerate (changelog ["changes" ]):
690689 if change .get ("id" ) == change_id :
691690 entry = change
692- entry_idx = i
693691 break
694692
695693 if entry is None :
@@ -881,7 +879,7 @@ def _compute_strategy_correlation() -> dict:
881879
882880def edit_file (file_path : str , old_string : str , new_string : str , rationale : str ) -> dict :
883881 """Edit a file with no-touch enforcement.
884-
882+
885883 Returns success/failure dict. Rejects edits to protected files and files
886884 in cooling period.
887885 """
@@ -931,7 +929,7 @@ def edit_file(file_path: str, old_string: str, new_string: str, rationale: str)
931929
932930def run_backtest (params : dict | None = None ) -> dict :
933931 """Run pipeline_backtest.py and return structured results.
934-
932+
935933 Enforces max invocations per run. params is a dict of CLI arguments.
936934 """
937935 global _backtests_this_run
@@ -1031,7 +1029,7 @@ def run_tests() -> dict:
10311029
10321030def create_experiment (experiment_id : str , hypothesis : str , variant : dict ) -> dict :
10331031 """Create a shadow-mode experiment.
1034-
1032+
10351033 variant should contain: file, parameter, baseline_value, variant_value.
10361034 Enforces max active experiment limit.
10371035 """
@@ -1095,7 +1093,7 @@ def create_experiment(experiment_id: str, hypothesis: str, variant: dict) -> dic
10951093
10961094def deploy_change (commit_message : str , evidence : dict ) -> dict :
10971095 """Atomic deploy: branch, commit, test, backtest, merge.
1098-
1096+
10991097 Enforces: budget, test pass, backtest Sharpe floor, safety invariants.
11001098 evidence dict should contain: sample_size, change_type, diagnosis.
11011099 """
@@ -1316,19 +1314,19 @@ def _update_pending_status(status: str, commit_sha: str | None = None, snapshot:
13161314
13171315def rollback_change (commit_sha : str , reason : str ) -> dict :
13181316 """Revert a specific agent-authored commit.
1319-
1317+
13201318 Only reverts commits authored by the agent (checks changelog).
13211319 Runs tests after revert to confirm clean state.
13221320 """
13231321 changelog = _load_changelog ()
1324-
1322+
13251323 # Find the change in changelog
13261324 change_entry = None
13271325 for change in changelog ["changes" ]:
13281326 if change .get ("commit_sha" ) == commit_sha :
13291327 change_entry = change
13301328 break
1331-
1329+
13321330 if change_entry is None :
13331331 return {"success" : False , "error" : f"Commit { commit_sha } not found in agent changelog — refusing to revert non-agent commits" }
13341332
@@ -1339,7 +1337,7 @@ def rollback_change(commit_sha: str, reason: str) -> dict:
13391337 dependent_shas = []
13401338 change_files = set (change_entry .get ("files_modified" , []))
13411339 change_ts = change_entry .get ("timestamp" , "" )
1342-
1340+
13431341 for other in changelog ["changes" ]:
13441342 if other .get ("commit_sha" ) == commit_sha :
13451343 continue
@@ -1415,7 +1413,7 @@ def rollback_change(commit_sha: str, reason: str) -> dict:
14151413
14161414def pause_strategy (strategy_name : str , reason : str ) -> dict :
14171415 """Write a pause flag for a strategy. Auto-expires after 3 days.
1418-
1416+
14191417 Valid strategies: screener, momentum, sentiment.
14201418 """
14211419 valid = {"screener" , "momentum" , "sentiment" }
@@ -1466,12 +1464,12 @@ def is_strategy_paused(strategy_name: str) -> bool:
14661464
14671465def log_decision (summary : str , details : dict ) -> dict :
14681466 """Log a decision to the changelog. REQUIRED every agent run.
1469-
1467+
14701468 Use for both action decisions and "do nothing" decisions.
14711469 """
14721470 _ensure_agent_dirs ()
14731471 changelog = _load_changelog ()
1474-
1472+
14751473 entry = {
14761474 "id" : f"dec-{ datetime .now ().strftime ('%Y%m%d-%H%M%S' )} " ,
14771475 "timestamp" : datetime .now ().isoformat (),
0 commit comments