Files
Claude 2d3a29e4b3 Apply lessons from studying real GitHub projects
Studied via direct fetches: SakanaAI/AI-Scientist-v2, WecoAI/aideml,
anthropics/skills, obra/superpowers, UniM0cha/claude-self-improving-
skills, SamuelSchmidgall/AgentLaboratory, princeton-nlp/SWE-agent,
openai/preparedness (PaperBench), open-mmlab/mmsegmentation,
facebookresearch/dinov2, karpathy/nanoGPT. Applied the top verified
findings:

- extract_commands: join backslash-continued commands (every dinov2 run
  command was previously truncated to an unrunnable `python ... \` stub)
  and classify entrypoint-first with word-boundary keywords (nanoGPT's
  `train.py ... --eval_iters=20` classified as evaluation, which would
  execute training while bypassing the authorization gate). Quick-start
  sections now count as run sections. Both real-repo patterns added as
  regression fixtures.
- research-thinking-loop: draft/debug/improve iteration types with a
  3-attempt debug cap (AIDE journal semantics), no-parsed-metric ⇒ buggy
  and never best, replication across 3 seeds before a candidate replaces
  current_research (AI-Scientist-v2 multi-seed evaluation), metric-only
  best selection note, typed stop reasons, defaults table, ledger-first
  grounding.
- annotate_readme: PaperBench-style evidence tiers per annotation
  (code-development / execution / result-match) and a weighted 0-1
  reproduction score in the header chip and readme_section_coverage.
- lessons_store: touch/prune lifecycle with usage-extended staleness
  windows, credential-shape blocklist (AKIA/ghp_/sk-/xox/AIza),
  best-effort security wording, what-NOT-to-record and human-reviewed
  promotion flow in the policy.
- Demo bundles and preview images regenerated with score and tiers.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HT2VAaQodjqTJdjBHSStxA
2026-07-26 18:22:07 +00:00

126 lines
4.5 KiB
Python

#!/usr/bin/env python3
"""Regression checks for the continuous-learning lesson store."""
from __future__ import annotations
import importlib.util
import json
import os
import shutil
import subprocess
import sys
import tempfile
from pathlib import Path
def load_module(repo_root: Path):
module_path = repo_root / "shared" / "scripts" / "lessons_store.py"
spec = importlib.util.spec_from_file_location("lessons_store", module_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
def main() -> int:
repo_root = Path(__file__).resolve().parents[1]
temp_root = Path(tempfile.mkdtemp(prefix="codex-lessons-store-", dir=repo_root))
checks = 0
old_home = os.environ.get("RIGORPILOT_HOME")
old_toggle = os.environ.get("RIGORPILOT_LESSONS")
try:
os.environ["RIGORPILOT_HOME"] = str(temp_root / "rigorpilot-home")
os.environ.pop("RIGORPILOT_LESSONS", None)
store = load_module(repo_root)
path = store.record_lesson(
kind="failure-fix",
skill="ai-research-reproduction",
summary="[partial] checkpoint missing",
detail="python eval.py",
fingerprint="demo@abc123",
)
if path is None or not path.exists():
raise AssertionError("lesson store did not persist a valid lesson")
checks += 1
store.record_lesson(kind="failure-fix", skill="ai-research-reproduction", summary="[partial] checkpoint missing")
if len(store.load_lessons()) != 1:
raise AssertionError("duplicate lesson was not deduplicated")
checks += 1
secret = store.record_lesson(kind="preference", skill="x", summary="api_key=sk-12345 leaked")
if secret is not None or len(store.load_lessons()) != 1:
raise AssertionError("secret-looking lesson was not refused")
checks += 1
store.record_lesson(kind="preference", skill="core", summary="Prefer zh reports")
overlay = store.summarize()
text = overlay.read_text(encoding="utf-8")
if "Prefer zh reports" not in text or "checkpoint missing" not in text:
raise AssertionError("overlay summary lost recorded lessons")
if "repository wins" not in text:
raise AssertionError("overlay lost the core-wins disclaimer")
checks += 2
os.environ["RIGORPILOT_LESSONS"] = "0"
disabled = store.record_lesson(kind="preference", skill="core", summary="should not persist")
if disabled is not None or len(store.load_lessons()) != 2:
raise AssertionError("RIGORPILOT_LESSONS=0 did not disable recording")
checks += 1
os.environ.pop("RIGORPILOT_LESSONS", None)
if not store.touch_lesson("Prefer zh reports"):
raise AssertionError("touch did not find the lesson by summary")
touched = [i for i in store.load_lessons() if i.get("summary") == "Prefer zh reports"][0]
if touched.get("use_count") != 1 or not touched.get("last_used"):
raise AssertionError("touch did not bump use_count/last_used")
checks += 1
import time as _time
removed = store.prune(now=int(_time.time()) + 400 * 86400)
if removed < 1:
raise AssertionError("prune did not drop stale lessons after the window")
checks += 1
cli = subprocess.run(
[
sys.executable,
str(repo_root / "shared" / "scripts" / "lessons_store.py"),
"record",
"--kind",
"user-correction",
"--skill",
"ai-research-explore",
"--summary",
"Researcher prefers mIoU over aAcc as headline metric",
],
capture_output=True,
text=True,
check=True,
env=os.environ.copy(),
)
payload = json.loads(cli.stdout)
if not payload.get("recorded"):
raise AssertionError("CLI record path failed")
checks += 1
print("ok: True")
print(f"checks: {checks}")
print("failures: 0")
return 0
finally:
if old_home is None:
os.environ.pop("RIGORPILOT_HOME", None)
else:
os.environ["RIGORPILOT_HOME"] = old_home
if old_toggle is None:
os.environ.pop("RIGORPILOT_LESSONS", None)
else:
os.environ["RIGORPILOT_LESSONS"] = old_toggle
if temp_root.exists():
shutil.rmtree(temp_root)
if __name__ == "__main__":
raise SystemExit(main())