Skip to content
Report library
Purpose / Development

Analyze Project Skill Security Audit

What the author says it does (original text)

Rigor Analyze / Rigor Audit read-only skill for deep learning research repositories. Use when the user wants to read and understand a repository, inspect model structure and training or inference entrypoints, review configs and insertion points, or flag suspicious implementation patterns without modifying code or running heavy jobs. Do not use for active command execution, broad refactoring, specu

Independent security check

Do not install or run it yet

Files checked
20
Risks found
6
Could it run dangerous commands?Looks for programs run straight after downloading, remote control of your computer, and hidden commands.Risks found: 1
Medium risk

Runs code that is decided at runtime

Source references: 2
What we found

The final command comes from a variable, so this static check cannot confirm exactly what will run.

Why this matters

The hidden content could run extra commands. We cannot yet tell what those commands would do.

Legitimate use of this code

This line does not invoke an interpreter or execute dynamic content. It only checks whether analyzed Python text contains both `.eval()` and `dropout`, then adds a heuristic review note. The cited code is static text inspection, not repository-code execution.

This assessment concerns the code and conditions shown, not proof that harm has occurred.
scripts/analyze_project.py:313In the codeOpen original file
            findings.append(f"{rel}: both `relu` and `sigmoid` appear in the same file; check activation order and intent.")        if ".eval()" in lower and "dropout" in lower:            findings.append(f"{rel}: review whether dropout-sensitive evaluation behavior is intentional.")
Show 1 other places
scripts/analyze_project.py:300In the codeOpen original file
    for path in python_files:        text = path.read_text(encoding="utf-8", errors="ignore")        rel = path.relative_to(repo).as_posix()        lower = text.lower()        if "attention" in lower or "transformer" in lower:            saw_attention = True        if any(token in lower for token in ["positional", "position_embedding", "position encoding", "pos_embed"]):            saw_position = True        if "sigmoid" in lower and lower.count("sigmoid") >= 2:            findings.append(f"{rel}: repeated `sigmoid` usage detected; review for duplicated post-processing.")        if "relu" in lower and "sigmoid" in lower:            findings.append(f"{rel}: both `relu` and `sigmoid` appear in the same file; check activation order and intent.")        if ".eval()" in lower and "dropout" in lower:            findings.append(f"{rel}: review whether dropout-sensitive evaluation behavior is intentional.")        if "optimizer" in lower and "requires_grad" not in lower and "param_groups" not in lower:
Could it expose your files or keys?Looks for uploads of files containing passwords or keys, and keys written directly in the code.Risks found: 4
High risk

A command auto-selected from the README runs locally with the full inherited environment

Source references: 5
What we found

With `--run-selected`, the orchestrator executes a command extracted and automatically selected from repository documentation. The runtime copies all of `os.environ` by default and then launches the process. A malicious or compromised README can therefore cause the selected program to read API keys, cloud credentials, and other session secrets and access the host or network.

Why this matters

The command could transmit credentials, private source, or local data and modify files or account state with the user's permissions. A timeout limits duration, not what the process can access before termination.

The risk is supported, but execution occurs only with explicit `--run-selected`. The orchestrator extracts and automatically selects a README command, then launches it locally; the runtime copies all of `os.environ` by default. A selected untrusted program could therefore read environment variables and use host or network access. The documentation explicitly says this is not an OS sandbox. Users can require command review, isolation, or a minimal child environment.

ai-research-reproduction/scripts/orchestrate_repro.py:1237In the codeOpen original file
    chosen = choose_goal(command_data.get("commands", []), repo_path)    dataset_hint = derive_dataset_hint(asset_data)    checkpoint_hint = derive_checkpoint_hint(asset_data)    run_data: Dict[str, Any] = {
Show 4 other places
ai-research-reproduction/scripts/orchestrate_repro.py:1292In the codeOpen original file
            )        else:            run_data = maybe_run_command(                repo_path,                chosen["documented_command"],                args.timeout,                args.user_language,                args.shell_mode,                runtime_root,                model_adapter,                args.monitor_gpu,            )
ai-research-reproduction/_bundled/shared/scripts/runtime_runner.py:487In the codeOpen original file
    try:        argv = build_command(command, shell_mode)        environment = dict(os.environ if child_env is None else child_env)        spec["requested_argv"] = list(argv)        atomic_write_json(run_dir / "spec.json", spec)        if shell_mode == "direct":            argv = resolve_direct_argv(argv, repo, environment)        spec["argv"] = list(argv)        atomic_write_json(run_dir / "spec.json", spec)        creationflags = subprocess.CREATE_NEW_PROCESS_GROUP if os.name == "nt" else 0        process = subprocess.Popen(            argv,            env=environment,            cwd=repo,            stdout=subprocess.PIPE,            stderr=subprocess.PIPE,            text=True,            encoding="utf-8",            errors="replace",            bufsize=1,            creationflags=creationflags,            start_new_session=os.name != "nt",        )    except (FileNotFoundError, ShellSyntaxRequired, OSError, ValueError) as exc:
ai-research-reproduction/scripts/orchestrate_repro.py:1167In the codeOpen original file
    scan_data = run_json(scan_script, ["--repo", str(repo_path), "--json"])    readme_path = scan_data.get("readme_path")    command_data: Dict[str, Any] = {"commands": [], "counts": {}, "warnings": []}    if readme_path:        command_data = run_json(extract_script, ["--readme", readme_path, "--json"])        command_data = delegate_to_docs(readme_path, extract_script, command_data)
ai-research-reproduction/scripts/orchestrate_repro.py:1272In the codeOpen original file
        )    elif args.run_selected:        if chosen["selected_goal"] == "training":            run_data = maybe_run_training(                repo_path=repo_path,                command=chosen["documented_command"],                train_script=train_execute_script,                lane=args.lane,                user_language=args.user_language,                full_training_authorized=args.full_training_authorized,                train_timeout=args.train_timeout,                dataset_hint=dataset_hint,                checkpoint_hint=checkpoint_hint,                resume_from=args.resume_from,                max_train_steps=args.max_train_steps,                shell_mode=args.shell_mode,                runtime_root=runtime_root,                model_profile_json=args.model_profile_json,                required_model_capabilities=args.require_model_capability,                gpu_monitor_enabled=not args.no_gpu_monitor,            )        else:            run_data = maybe_run_command(                repo_path,                chosen["documented_command"],                args.timeout,                args.user_language,                args.shell_mode,                runtime_root,                model_adapter,                args.monitor_gpu,            )
Medium risk

The model runner can send private repository contents to Anthropic or a custom endpoint

Source references: 4
What we found

The model tool can read files from the initial repository inventory and places the results into the persistent message history; the next `provider.complete` sends those messages. Configuration may use `ANTHROPIC_BASE_URL` or a specified HTTPS endpoint. Source and configuration content can therefore leave the machine, not just command results.

Why this matters

Private source, internal paths, sample data, or secrets not otherwise excluded may be received by the model service or custom gateway and may also appear in persistent traces.

The model runner lets the model read up to 12,000 characters from files in the initial inventory, adds tool results to later messages, and passes those messages to `provider.complete`. This entry point uses the Anthropic protocol, while its documentation permits the official service, `ANTHROPIC_BASE_URL`, or a configured HTTPS endpoint. Thus private code or configuration read through this optional runner may be sent to the chosen service. Users can restrict readable content and verify the endpoint and privacy terms.

ai-research-reproduction/scripts/run_agent.py:438In the codeOpen original file
                    try:                        if name == "list_files":                            value = {"files": sorted(files)}                        elif name == "read_file":                            if args["path"] not in files:                                raise ValueError("File was not in the permitted initial inventory")                            offset = max(0, int(args.get("offset", 0)))                            with safe_file(repo, args["path"]).open("r", encoding="utf-8") as handle:                                handle.seek(offset)                                value = {"path": args["path"], "text": handle.read(12000), "next_offset": handle.tell()}                        elif name == "update_plan":
Show 3 other places
ai-research-reproduction/scripts/run_agent.py:495In the codeOpen original file
                        value = {"error": str(exc)}                    event("tool_result", tool=name, result=value)                    state["tool_results"].append({"type": "tool_result", "tool_use_id": call["id"],                        "content": json.dumps(value, ensure_ascii=False), "is_error": "error" in value})                    state["pending"].pop(0)                    tools_this_turn += 1                    save()                    if pause_after_tools and tools_this_turn >= pause_after_tools and state["status"] == "running":                        state["status"] = "paused"                        event("paused", reason="Explicit test/session checkpoint")                    continue                if state["tool_results"]:                    state["messages"].append({"role": "user", "content": state.pop("tool_results")})                    state["tool_results"] = []                request_bytes = len(json.dumps([SYSTEM, TOOLS, state["messages"]]).encode())                used = sum(state["usage"].values())                reserve = request_bytes + budget["max_output_tokens"] + 1024                if state["model_calls"] >= budget["max_model_calls"] or used + reserve > budget["max_total_tokens"]:                    block("Model call/token reservation budget reached")                    break                state["model_calls"] += 1                state["model_pending"] = True                state["usage_complete"] = False                save()                event("model_request", call=state["model_calls"], reserved_tokens=reserve)                response = provider.complete(state["messages"], SYSTEM, TOOLS, budget["max_output_tokens"], min(60, remaining))                if not isinstance(response, dict):
ai-research-reproduction/references/agent-runner.md:110In the instructionsOpen original file
`endpoint` optionally names the final HTTPS endpoint. Without it, the clientuses `ANTHROPIC_BASE_URL` or the official endpoint. For an already configuredBearer gateway, set `metadata.auth_scheme` to `bearer` and name its credentialenvironment variable. Redirects are refused so credentials are not forwarded.
ai-research-reproduction/scripts/run_agent.py:570In the codeOpen original file
    args = parser.parse_args()    profile = load_model_profile(Path(args.model_profile))    if profile["provider"] != "anthropic":        parser.error("P1 supports the Anthropic Messages protocol; other adapters remain metadata-only")    task = json.loads(Path(args.task).read_text(encoding="utf-8-sig"))    state = run(task, Path(args.repo), Path(args.output), profile, AnthropicProvider(profile),                resume=args.resume, pause_after_tools=args.pause_after_tools, source_adjacent_readme=args.source_adjacent_readme)    print(json.dumps({**{k: state[k] for k in ["status", "model_calls", "tool_calls", "usage", "verification"]},
Medium risk

The analyzer may follow repository file symlinks and read content outside the repository

Source references: 4
What we found

The analyzer directly calls `read_text` on paths returned by `repo.rglob("*.py")` without resolving and confirming that each target remains inside the repository, unlike the model runner's scope check. A Python-file symlink to an external file is therefore read, and extracted symbols or heuristic conclusions can enter reports.

Why this matters

A repository can induce access to local files the user did not authorize for audit and write structural information from them into analysis outputs. Sharing or uploading those outputs can cause indirect disclosure.

The analyzer recursively collects `*.py` paths and calls `read_text` without resolving each target and checking that it remains inside the repository. Reading a file symlink follows its target, so an in-repository symlink to an external Python file may expose that text. Its content can produce path-labelled heuristic findings written to `RISKS.md`. This requires such a symlink and read permission. Users can require analysis in an isolated copy and rejection of escaping symlinks.

scripts/analyze_project.py:294In the codeOpen original file
def collect_suspicious_patterns(repo: Path) -> List[str]:    findings: List[str] = []    python_files = [path for path in repo.rglob("*.py") if "__pycache__" not in path.parts]    saw_attention = False    saw_position = False    for path in python_files:        text = path.read_text(encoding="utf-8", errors="ignore")        rel = path.relative_to(repo).as_posix()        lower = text.lower()
Show 3 other places
scripts/analyze_project.py:247In the codeOpen original file
    for rel in candidate_paths[:24]:        path = repo / rel        if not path.exists() or path.suffix.lower() != ".py":            continue        try:            tree = ast.parse(path.read_text(encoding="utf-8", errors="ignore"))        except SyntaxError:            continue        for node in ast.walk(tree):            if isinstance(node, ast.ClassDef):                symbol_hints.append(f"{rel}:{node.name}")                has_init = any(isinstance(item, ast.FunctionDef) and item.name == "__init__" for item in node.body)                has_forward = any(isinstance(item, ast.FunctionDef) and item.name == "forward" for item in node.body)                if has_init:                    constructor_candidates.append(f"{rel}:{node.name}")                if has_forward:                    forward_candidates.append(f"{rel}:{node.name}.forward")            elif isinstance(node, ast.FunctionDef):                symbol_hints.append(f"{rel}:{node.name}")                if node.name in {"forward", "__call__", "predict"}:
scripts/analyze_project.py:309In the codeOpen original file
            saw_position = True        if "sigmoid" in lower and lower.count("sigmoid") >= 2:            findings.append(f"{rel}: repeated `sigmoid` usage detected; review for duplicated post-processing.")        if "relu" in lower and "sigmoid" in lower:            findings.append(f"{rel}: both `relu` and `sigmoid` appear in the same file; check activation order and intent.")        if ".eval()" in lower and "dropout" in lower:            findings.append(f"{rel}: review whether dropout-sensitive evaluation behavior is intentional.")        if "optimizer" in lower and "requires_grad" not in lower and "param_groups" not in lower:            findings.append(f"{rel}: verify optimizer parameter coverage if custom freezing is expected.")
scripts/analyze_project.py:588In the codeOpen original file
    risks = [        "# Suspicious Patterns",        "",    ]    patterns = data["suspicious_patterns"]    if patterns:        risks.extend(f"- {item}" for item in patterns)    else:        risks.append("- No high-signal suspicious patterns were detected by the lightweight heuristic pass.")    risks.append("")    (output_dir / "RISKS.md").write_text("\n".join(risks), encoding="utf-8")
Medium risk

Default lesson recording persistently stores failure summaries and documented commands outside the workspace

Source references: 7
What we found

Unless `RIGORPILOT_LESSONS=0` is set, reproduction runs append blocker summaries, documented commands, and repository fingerprints to `~/.rigorpilot/lessons.jsonl`. The filter recognizes only a limited set of credential keywords and common token formats; ordinary private URLs, usernames, internal paths, or unrecognized secrets may still be stored.

Why this matters

Sensitive project clues persist across repositories and sessions in the user's home directory and may be read by backups, other processes on a shared machine, or later reports. Cleaning the workspace does not remove them.

Lesson recording is enabled by default. After a selected run, partial or blocked results append a summary, documented command, and repository fingerprint to `~/.rigorpilot/lessons.jsonl` (or `RIGORPILOT_HOME`), outside the workspace. The filter is only a limited regular expression and the policy says it is not a guarantee, so internal paths, private URLs, personal data, or unrecognized secrets may persist until separately removed or pruned. Users can set `RIGORPILOT_LESSONS=0` before running and review the store.

ai-research-reproduction/_bundled/shared/scripts/lessons_store.py:20In the codeOpen original file
VALID_KINDS = {"failure-fix", "user-correction", "preference", "generalization"}# Best-effort blocklist: keyword shapes plus common bare-credential formats.# This is a guardrail, not a guarantee — callers still must not pass secrets.SECRET_RE = re.compile(    r"(api[_-]?key|secret|token|password|passwd|authorization|bearer\s+\S|-----BEGIN"    r"|AKIA[0-9A-Z]{16}|ghp_[A-Za-z0-9]{20,}|gho_[A-Za-z0-9]{20,}|sk-[A-Za-z0-9_-]{16,}"    r"|xox[a-z]-[A-Za-z0-9-]{10,}|AIza[0-9A-Za-z_-]{30,})",    re.IGNORECASE,)MAX_FIELD_CHARS = 300SUMMARY_LIMIT_PER_KIND = 12
Show 6 other places
ai-research-reproduction/_bundled/shared/scripts/lessons_store.py:117In the codeOpen original file
    entry = {        "ts": int(time.time()),        "kind": kind,        "skill": sanitize(skill) or "unknown",        "summary": clean_summary,        "detail": clean_detail,        "fingerprint": sanitize(fingerprint) or "",    }    path = lessons_path()    path.parent.mkdir(parents=True, exist_ok=True)    with path.open("a", encoding="utf-8") as handle:        handle.write(json.dumps(entry, ensure_ascii=False) + "\n")    return path
ai-research-reproduction/scripts/orchestrate_repro.py:1391In the codeOpen original file
    context["lesson_recorded"] = maybe_record_lesson(repo_path, context) if args.run_selected else None
ai-research-reproduction/SKILL.md:123In the instructionsOpen original file
- Load `references/deep-learning-experiment-principles.md` when dataset, split, metric, checkpoint, training, or evaluation details matter.- Consult `~/.rigorpilot/PERSONAL_RIGOR.md` if present, under `references/continuous-learning-policy.md` (advisory only; core wins).- Failed and later-resolved runs are auto-recorded as lessons via `shared/scripts/lessons_store.py` (`RIGORPILOT_LESSONS=0` disables).- Load `references/research-safety-principles.md` before protocol-sensitive
ai-research-reproduction/_bundled/shared/scripts/lessons_store.py:41In the codeOpen original file
def lessons_home() -> Path:    root = os.environ.get("RIGORPILOT_HOME")    return Path(root).expanduser() if root else Path.home() / ".rigorpilot"def lessons_enabled() -> bool:    return os.environ.get("RIGORPILOT_LESSONS", "1") != "0"
ai-research-reproduction/_bundled/shared/scripts/lessons_store.py:67In the codeOpen original file
def sanitize(text: str) -> Optional[str]:    cleaned = " ".join(str(text or "").split())[:MAX_FIELD_CHARS]    if not cleaned:        return None    if SECRET_RE.search(cleaned):        return None    return cleaned
ai-research-reproduction/scripts/orchestrate_repro.py:62In the codeOpen original file
    try:        if status in {"partial", "blocked"}:            path = store.record_lesson(                kind="failure-fix",                skill="ai-research-reproduction",                summary=f"[{status}] {context.get('main_blocker', 'unrecorded blocker')}",                detail=str(context.get("documented_command") or ""),                fingerprint=fingerprint,            )            return str(path) if path else None
Could it delete files or keep running?Looks for broad file deletion, disk overwrites, and programs set to start automatically.Risks found: 1
Medium risk

The “read-only” analysis silently overwrites fixed filenames in its output directory

Source references: 5
What we found

Without `--json`, the analyzer uses `write_text` for `SUMMARY.md`, `RISKS.md`, several map files, and `status.json`. The user can select any `--output-dir`, and the code does not check whether those files already exist or require an ownership receipt or backup.

Why this matters

Existing notes, reports, or state files with those names are irreversibly replaced. The “read-only” label may cause users to underestimate this write behavior.

Here, “read-only” protects the analyzed repository code; it does not mean the skill performs no writes, because analysis outputs are explicitly expected. In non-`--json` mode, any `--output-dir` is accepted and fixed filenames are written with `write_text` without checking for existing files. Pointing it at a directory containing a valuable `SUMMARY.md`, `RISKS.md`, or `status.json` would overwrite those files. Users can choose a new dedicated output directory and check for name collisions first.

scripts/analyze_project.py:567In the codeOpen original file
def write_outputs(output_dir: Path, data: Dict[str, object]) -> None:    output_dir.mkdir(parents=True, exist_ok=True)    summary = [        "# Project Analysis Summary",        "",        *[f"- {line}" for line in data["summary_lines"]],        "",        "## Conservative Suggestions",        "",        *[f"- {line}" for line in data["conservative_suggestions"]],        "",        "## Additional Documents",        "",        "- `RESEARCH_MAP.md`",        "- `CHANGE_MAP.md`",        "- `EVAL_CONTRACT.md`",        "",    ]    (output_dir / "SUMMARY.md").write_text("\n".join(summary), encoding="utf-8")
Show 4 other places
scripts/analyze_project.py:588In the codeOpen original file
    risks = [        "# Suspicious Patterns",        "",    ]    patterns = data["suspicious_patterns"]    if patterns:        risks.extend(f"- {item}" for item in patterns)    else:        risks.append("- No high-signal suspicious patterns were detected by the lightweight heuristic pass.")    risks.append("")    (output_dir / "RISKS.md").write_text("\n".join(risks), encoding="utf-8")
scripts/analyze_project.py:631In the codeOpen original file
    }    (output_dir / "status.json").write_text(json.dumps(status, indent=2, ensure_ascii=False), encoding="utf-8")def main() -> int:    parser = argparse.ArgumentParser(description="Analyze a deep learning research repository conservatively.")    parser.add_argument("--repo", required=True, help="Path to the target repository.")    parser.add_argument("--output-dir", default="analysis_outputs", help="Directory for analysis outputs.")    parser.add_argument("--analysis-context-json", default="", help="Optional analysis context JSON or YAML path.")    parser.add_argument("--json", action="store_true", help="Emit JSON to stdout instead of writing files.")    args = parser.parse_args()    repo = Path(args.repo).resolve()    context = load_context(args.analysis_context_json)    data = analyze_repo(repo, context)    if args.json:        print(json.dumps(data, indent=2, ensure_ascii=False))        return 0    write_outputs(Path(args.output_dir).resolve(), data)    print(json.dumps(data, indent=2, ensure_ascii=False))    return 0
SKILL.md:29In the instructionsOpen original file
## Clear boundaries- This skill is read-mostly.- It may run lightweight static inspection helpers.- It does not patch repository code.- It does not own final reproduction outputs.- It should mark suspicious patterns as heuristics, not confirmed bugs.## Output expectations- `analysis_outputs/SUMMARY.md`- `analysis_outputs/RISKS.md`- `analysis_outputs/status.json`
scripts/analyze_project.py:586In the codeOpen original file
    ]    (output_dir / "SUMMARY.md").write_text("\n".join(summary), encoding="utf-8")    risks = [        "# Suspicious Patterns",        "",    ]    patterns = data["suspicious_patterns"]    if patterns:        risks.extend(f"- {item}" for item in patterns)    else:        risks.append("- No high-signal suspicious patterns were detected by the lightweight heuristic pass.")    risks.append("")    (output_dir / "RISKS.md").write_text("\n".join(risks), encoding="utf-8")
Could it bypass safety checks?Looks for skipped website security checks, excessive file access, or actions that skip your approval.No risks found
Could it mislead the AI or hide text?Checks the skill instructions for requests to ignore you, influence the report, or hide text in invisible characters.No risks found
Could it change links or payment recipients without asking?Looks for forced referral or payment changes combined with instructions to hide the change.No risks found

Inside this skill

5 instruction sections

The top-level `analyze-project` implementation recursively inspects repository files, parses Python ASTs, and generates entrypoint, structure, and heuristic suspicious-pattern reports. It does not patch repository source, but it writes analysis artifacts by default.

View source
SKILL.md:31In the instructionsOpen original file
- This skill is read-mostly.- It may run lightweight static inspection helpers.- It does not patch repository code.- It does not own final reproduction outputs.- It should mark suspicious patterns as heuristics, not confirmed bugs.
scripts/analyze_project.py:425In the codeOpen original file
    candidates = collect_candidates(repo, task_family, tokens)    focus_files = collect_task_focus_files(repo, task_family, tokens)    data_interface_files = collect_data_interface_files(repo, task_family)    suspicious = collect_suspicious_patterns(repo)    output_hints = collect_output_hints(repo, evaluation_source)    module_files = collect_module_files(candidates, focus_files)    metric_files = collect_metric_files(candidates, focus_files)    symbol_info = collect_symbol_hints(repo, unique_limit(module_files + metric_files + candidates["train"] + candidates["eval"], 30))    config_binding_hints = collect_config_binding_hints(repo, unique_limit(candidates["config"] + focus_files + output_hints, 30))    research_map = build_research_map(repo, readme or repo / "README.md", task_family, candidates, focus_files, output_hints)

The supplied package also contains a broader reproduction skill. It extracts commands from the README and linked local documentation, and attempts the selected command only when `--run-selected` is supplied.

View source
ai-research-reproduction/scripts/orchestrate_repro.py:1167In the codeOpen original file
    scan_data = run_json(scan_script, ["--repo", str(repo_path), "--json"])    readme_path = scan_data.get("readme_path")    command_data: Dict[str, Any] = {"commands": [], "counts": {}, "warnings": []}    if readme_path:        command_data = run_json(extract_script, ["--readme", readme_path, "--json"])        command_data = delegate_to_docs(readme_path, extract_script, command_data)
ai-research-reproduction/scripts/orchestrate_repro.py:1106In the codeOpen original file
    parser.add_argument("--no-gpu-monitor", action="store_true", help="Disable NVIDIA telemetry for training commands.")    parser.add_argument("--user-language", default="en", help="Language tag for human-readable reports.")    parser.add_argument("--run-selected", action="store_true", help="Execute the selected documented command.")    parser.add_argument("--include-analysis-pass", action="store_true", help="Run analyze-project and record its outputs in the stage ledger.")    parser.add_argument(

The optional model-driven entrypoint uses the Anthropic Messages protocol. The model can select only command IDs pre-reviewed in the task JSON, but execution still occurs as a local process rather than inside an OS sandbox.

View source
ai-research-reproduction/scripts/run_agent.py:47In the codeOpen original file
TOOLS = [    tool("list_files", "List the initial repository file inventory", {}, []),    tool("read_file", "Read a UTF-8 repository file, optionally from an offset", {        "path": {"type": "string"}, "offset": {"type": "integer", "minimum": 0}}, ["path"]),    tool("update_plan", "Record completed and remaining work", {        "steps": {"type": "array", "items": {"type": "string"}}}, ["steps"]),    tool("run_command", "Execute a reviewed command ID; cannot change its argv", {        "command_id": {"type": "string"}}, ["command_id"]),    tool("finish", "Request independent final verification", {"summary": {"type": "string"}}, ["summary"]),]
ai-research-reproduction/references/agent-runner.md:16In the instructionsOpen original file
This is local execution with credential environment filtering, not an OS sandbox.Approved programs can access the host and network; use only trusted repositoriesuntil an isolated executor is configured. Commands that change scientificconditions must be explicitly reviewed. P1 targets small evaluations, not fulltraining or autonomous source repair.

The reproduction flow enables a cross-run personal lesson store by default. Blocked, partial, or later-resolved runs may append a summary, command detail, and repository fingerprint under the user's home directory.

View source
ai-research-reproduction/_bundled/shared/scripts/lessons_store.py:41In the codeOpen original file
def lessons_home() -> Path:    root = os.environ.get("RIGORPILOT_HOME")    return Path(root).expanduser() if root else Path.home() / ".rigorpilot"def lessons_enabled() -> bool:    return os.environ.get("RIGORPILOT_LESSONS", "1") != "0"
ai-research-reproduction/scripts/orchestrate_repro.py:62In the codeOpen original file
    try:        if status in {"partial", "blocked"}:            path = store.record_lesson(                kind="failure-fix",                skill="ai-research-reproduction",                summary=f"[{status}] {context.get('main_blocker', 'unrecorded blocker')}",                detail=str(context.get("documented_command") or ""),                fingerprint=fingerprint,            )            return str(path) if path else None
Start here · InstructionsSKILL.md
analyze-project
Lines connect the instruction file to its sections, not an observed execution order. Select a section to read the source.

File reference map

References: 20
Files making referencesReferenced content
Lines show actual file references, not execution order. Select a node to highlight its connections and inspect the files and source locations. Dashed lines include files that still need locating.
Files and check records20 files

Coverage and gaps

Content covered in each file

These are the source ranges included in this check, not a guarantee that every issue has been resolved.

  • SKILL.mdFull text included
  • ai-research-reproduction/_bundled/shared/scripts/lessons_store.pyFull text included
  • ai-research-reproduction/_bundled/shared/scripts/runtime_runner.pyFull text included
  • ai-research-reproduction/_bundled/shared/scripts/task_queue.pyFull text included
  • ai-research-reproduction/scripts/orchestrate_repro.pyFull text included
  • ai-research-reproduction/scripts/run_agent.pyFull text included
  • scripts/analyze_project.pyFull text included
  • references/analysis-policy.mdFull text included
  • ai-research-reproduction/references/agent-operating-principles.mdFull text included
  • ai-research-reproduction/references/agent-runner.mdFull text included
  • ai-research-reproduction/references/continuous-learning-policy.mdFull text included
  • ai-research-reproduction/references/deep-learning-experiment-principles.mdFull text included
  • ai-research-reproduction/references/language-policy.mdFull text included
  • ai-research-reproduction/references/output-spec.mdFull text included
  • ai-research-reproduction/references/patch-policy.mdFull text included
  • ai-research-reproduction/references/research-rigor-principles.mdFull text included
  • ai-research-reproduction/references/research-safety-principles.mdFull text included
  • ai-research-reproduction/references/runtime-and-model-adapter.mdFull text included
  • ai-research-reproduction/SKILL.mdFull text included
  • agents/openai.yamlFull text included

This report is for the version above. We read the available code and instructions without running the skill or checking extra packages it installs. This is not a promise of safety: a different version or setup may behave differently.

  • SKILL.mdInstructions
  • agents/openai.yamlSupporting file
  • references/analysis-policy.mdSupporting file
  • scripts/analyze_project.pyScript
  • ai-research-reproduction/SKILL.mdSupporting file
  • ai-research-reproduction/references/agent-operating-principles.mdSupporting file
  • ai-research-reproduction/references/research-rigor-principles.mdSupporting file
  • ai-research-reproduction/references/deep-learning-experiment-principles.mdSupporting file
  • ai-research-reproduction/scripts/orchestrate_repro.pyScript
  • ai-research-reproduction/references/runtime-and-model-adapter.mdSupporting file
  • ai-research-reproduction/references/agent-runner.mdSupporting file
  • ai-research-reproduction/scripts/run_agent.pyScript
  • ai-research-reproduction/references/patch-policy.mdSupporting file
  • ai-research-reproduction/references/output-spec.mdSupporting file
  • ai-research-reproduction/references/language-policy.mdSupporting file
  • ai-research-reproduction/references/continuous-learning-policy.mdSupporting file
  • ai-research-reproduction/_bundled/shared/scripts/lessons_store.pyScript
  • ai-research-reproduction/references/research-safety-principles.mdSupporting file
  • ai-research-reproduction/_bundled/shared/scripts/runtime_runner.pyScript
  • ai-research-reproduction/_bundled/shared/scripts/task_queue.pyScript

Operations mentioned in code and instructions

Read files
scripts/analyze_project.py:50In the codeOpen original file
    context_path = Path(path).resolve()    text = context_path.read_text(encoding="utf-8-sig")    if context_path.suffix.lower() == ".json":
scripts/analyze_project.py:252In the codeOpen original file
        try:            tree = ast.parse(path.read_text(encoding="utf-8", errors="ignore"))        except SyntaxError:
scripts/analyze_project.py:288In the codeOpen original file
            continue        text = path.read_text(encoding="utf-8", errors="ignore").lower()        if any(pattern in text for pattern in patterns):
Change files
scripts/analyze_project.py:505In the codeOpen original file
    ]    (output_dir / "RESEARCH_MAP.md").write_text("\n".join(lines), encoding="utf-8")
scripts/analyze_project.py:534In the codeOpen original file
    ]    (output_dir / "CHANGE_MAP.md").write_text("\n".join(lines), encoding="utf-8")
scripts/analyze_project.py:564In the codeOpen original file
    ]    (output_dir / "EVAL_CONTRACT.md").write_text("\n".join(lines), encoding="utf-8")
Run commands
ai-research-reproduction/scripts/orchestrate_repro.py:12In the codeOpen original file
import shleximport subprocessimport sys
ai-research-reproduction/scripts/orchestrate_repro.py:103In the codeOpen original file
    child_env["PYTHONIOENCODING"] = "utf-8"    result = subprocess.run(        command,
ai-research-reproduction/scripts/orchestrate_repro.py:121In the codeOpen original file
    try:        subprocess.run(            [
Read keys or account settings
ai-research-reproduction/scripts/orchestrate_repro.py:101In the codeOpen original file
    command = [sys.executable, str(script), *args]    child_env = os.environ.copy()    child_env["PYTHONIOENCODING"] = "utf-8"
ai-research-reproduction/scripts/run_agent.py:65In the codeOpen original file
    path = (repo / name).resolve()    if (not path.is_relative_to(repo) or any(p == ".git" or p.startswith(".env") for p in Path(name).parts)            or any(p == ".git" or p.startswith(".env") for p in path.relative_to(repo).parts)):
ai-research-reproduction/scripts/run_agent.py:66In the codeOpen original file
    if (not path.is_relative_to(repo) or any(p == ".git" or p.startswith(".env") for p in Path(name).parts)            or any(p == ".git" or p.startswith(".env") for p in path.relative_to(repo).parts)):        raise ValueError("File path is outside the permitted repository scope")
Install extra software packages
ai-research-reproduction/scripts/orchestrate_repro.py:252In the codeOpen original file
        score -= 10    if text_value.startswith(("pip install", "conda install", "conda env create", "conda activate", "git clone", "cd ")):        score -= 12
Connect to websites
ai-research-reproduction/scripts/orchestrate_repro.py:357In the codeOpen original file
        rel = match.group(1)        if rel.startswith(("http://", "https://")):            continue
ai-research-reproduction/scripts/run_agent.py:343In the codeOpen original file
        raise ValueError("All budget limits must be positive integers")    endpoint_identity = fingerprint(profile.get("endpoint") or os.getenv("ANTHROPIC_BASE_URL") or "https://api.anthropic.com")    harness_identity = fingerprint([Path(__file__).read_bytes().replace(b"\r\n", b"\n").hex(), SYSTEM, TOOLS,
ai-research-reproduction/references/runtime-and-model-adapter.md:65In the instructionsOpen original file
  "capabilities": ["text", "tool_calling", "structured_output"],  "endpoint": "https://gateway.example/v1",  "credential_env": "LAB_MODEL_API_KEY",
Lines read
5,436
File checksum (to compare versions)
1754df5ebbb44a172a0d8fe10b695bfdaa5a37d3a2cca2f3cc5d4f72ea4918df