Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
A comprehensive collection of Agent Skills for context engineering, multi-agent architectures, and production agent systems.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
researcher/scripts/loop_daily.py
1#!/usr/bin/env python32"""Daily ops for the autonomous research loop.34Runs the deterministic gates, the benchmark harness, and writes a dated5snapshot report. Designed to be idempotent: running twice in a day overwrites6the same dated snapshot but appends to benchmark history each time.7"""89from __future__ import annotations1011import argparse12import json13import subprocess14import sys15from pathlib import Path16from typing import Any1718from loop_common import (19QUEUE_DIR,20REPORTS_DIR,21RESEARCHER,22ROOT,23SNAPSHOTS_DIR,24categorize_runs,25load_config,26load_run_state,27read_jsonl,28today_utc,29utc_now,30)313233def run_subprocess(cmd: list[str]) -> dict[str, Any]:34completed = subprocess.run(cmd, cwd=ROOT, capture_output=True, text=True, check=False)35parsed: Any = None36if completed.stdout.strip():37try:38parsed = json.loads(completed.stdout)39except json.JSONDecodeError:40parsed = None41return {42"exit_code": completed.returncode,43"passed": completed.returncode == 0,44"stdout_json": parsed,45"stderr": completed.stderr.strip(),46}474849def run_repo_validation() -> dict[str, Any]:50return run_subprocess([sys.executable, str(RESEARCHER / "scripts" / "validate_repo.py"), "--json"])515253def run_benchmarks() -> dict[str, Any]:54return run_subprocess([sys.executable, str(RESEARCHER / "scripts" / "run_benchmarks.py"), "--record", "--json"])555657def run_activation_cases() -> dict[str, Any]:58return run_subprocess([sys.executable, str(RESEARCHER / "scripts" / "check_activation_cases.py"), "--json"])596061def run_run_validations() -> dict[str, Any]:62buckets = categorize_runs()63results: list[dict[str, Any]] = []64for run_dir in buckets["active"] + buckets["parked"]:65result = run_subprocess(66[67sys.executable,68str(RESEARCHER / "scripts" / "validate_run.py"),69"--run-dir",70str(run_dir),71"--json",72]73)74results.append({"run_id": run_dir.name, **result})75return {76"checked": len(results),77"passing": sum(1 for record in results if record.get("passed")),78"results": results,79}808182def queue_snapshot() -> dict[str, Any]:83buckets = categorize_runs()84inbox = read_jsonl(QUEUE_DIR / "inbox.jsonl")85parked = read_jsonl(QUEUE_DIR / "parked.jsonl")86done = read_jsonl(QUEUE_DIR / "done.jsonl")87quarantine = read_jsonl(QUEUE_DIR / "quarantine.jsonl")88return {89"inbox": len(inbox),90"active": len(buckets["active"]),91"parked": len(parked),92"closed": len(buckets["closed"]),93"done_ledger": len(done),94"quarantine": len(quarantine),95"unknown": len(buckets["unknown"]),96}979899def claims_due_for_review() -> list[dict[str, Any]]:100claims_path = RESEARCHER / "claims" / "index.jsonl"101if not claims_path.exists():102return []103today = today_utc()104due: list[dict[str, Any]] = []105for line in claims_path.read_text(encoding="utf-8").splitlines():106if not line.strip():107continue108try:109record = json.loads(line)110except json.JSONDecodeError:111continue112if record.get("volatility") == "high":113last_reviewed = record.get("last_reviewed", "")114if last_reviewed < today:115due.append({"claim_id": record.get("claim_id"), "owning_skill": record.get("owning_skill"), "last_reviewed": last_reviewed})116return due117118119def render_snapshot(120timestamp: str,121repo: dict[str, Any],122activation: dict[str, Any],123benchmarks: dict[str, Any],124run_validations: dict[str, Any],125queue: dict[str, Any],126claims: list[dict[str, Any]],127) -> str:128lines = [129f"# Researcher Snapshot {timestamp}",130"",131"## Queue",132f"- inbox: {queue['inbox']}",133f"- active runs: {queue['active']}",134f"- parked runs: {queue['parked']}",135f"- closed runs (state): {queue['closed']}",136f"- done ledger entries: {queue['done_ledger']}",137f"- quarantined sources: {queue['quarantine']}",138f"- unknown run state: {queue['unknown']}",139"",140"## Gates",141f"- repo validation: {'passed' if repo.get('passed') else 'failed'}",142f"- activation cases: {'passed' if activation.get('passed') else 'failed'}",143f"- benchmark harness: {'passed' if benchmarks.get('passed') else 'failed'}",144f"- per-run validations: {run_validations['passing']}/{run_validations['checked']} passing",145"",146"## Volatile Claims Due For Review",147]148if not claims:149lines.append("- none")150else:151for claim in claims:152lines.append(153f"- {claim['claim_id']} ({claim['owning_skill']}) last reviewed {claim['last_reviewed'] or 'never'}"154)155lines.extend(156[157"",158"## Parked Runs",159]160)161parked = read_jsonl(QUEUE_DIR / "parked.jsonl")162if not parked:163lines.append("- none")164else:165for record in parked:166lines.append(f"- {record.get('run_id')}: {record.get('reason')} (parked {record.get('parked_at')})")167return "\n".join(lines) + "\n"168169170def daily(config: dict[str, Any]) -> dict[str, Any]:171timestamp = utc_now()172today = today_utc()173repo = run_repo_validation()174activation = run_activation_cases()175benchmarks = run_benchmarks()176run_validations = run_run_validations()177queue = queue_snapshot()178claims = claims_due_for_review()179180snapshot_text = render_snapshot(timestamp, repo, activation, benchmarks, run_validations, queue, claims)181snapshot_path = SNAPSHOTS_DIR / f"{today}.md"182snapshot_path.parent.mkdir(parents=True, exist_ok=True)183snapshot_path.write_text(snapshot_text, encoding="utf-8")184185summary = {186"timestamp": timestamp,187"snapshot": str(snapshot_path.relative_to(ROOT)),188"passing": all([repo.get("passed"), activation.get("passed"), benchmarks.get("passed")]),189"queue": queue,190"claims_due_for_review": len(claims),191"run_validations": {192"checked": run_validations["checked"],193"passing": run_validations["passing"],194},195}196return summary197198199def main() -> int:200parser = argparse.ArgumentParser(description="Run daily ops for the autonomous research loop")201parser.add_argument("--json", action="store_true")202args = parser.parse_args()203204config = load_config()205result = daily(config)206if args.json:207print(json.dumps(result, indent=2))208else:209print(210f"daily: snapshot={result['snapshot']} "211f"queue=inbox{result['queue']['inbox']}/active{result['queue']['active']}/parked{result['queue']['parked']} "212f"all_gates_pass={result['passing']}"213)214return 0 if result["passing"] else 1215216217if __name__ == "__main__":218sys.exit(main())219