Rigor Explore compatible skill slug for meaningful and potentially novel deep learning research candidates. Use when the researcher has chosen the task family, dataset, benchmark, evaluation method, provided SOTA references, and wants candidate-only exploration on top of `current_research` with auditable repo understanding, idea gating, fair comparison, and governed experiments written to `explore
Independent security check
Do not install or run it yet
This check is incomplete. Only available results are shown below.
Files checked
79
Risks found
14
Could it run dangerous commands?Looks for programs run straight after downloading, remote control of your computer, and hidden commands.Risks found: 5
High risk
Campaign mode automatically executes the configured evaluation command
Source references: 7
What we found
`evaluation_source.command` is bound as a command, and every non-compatibility campaign invokes baseline evaluation independently of `--run-selected-variants`. The execution helper receives and runs that string in the target repository.
Why this matters
If the campaign file is untrusted or the user expected planning only, the command can read or modify files available to the account, start network processes, or consume CPU/GPU resources.
When a campaign file selects non-compatibility mode, the orchestrator calls baseline evaluation regardless of `--run-selected-variants`. The evaluation string is then passed as `--command` to a helper that runs it in the target worktree. A malicious, stale, or destructive `evaluation_source.command` could therefore modify files, consume compute, or access credentials available to the process. Users can ask for a separate opt-in for baseline execution and restrict commands, environment variables, network access, and writable paths.
1987 parser.add_argument("--include-setup-pass", action="store_true", help="Include env-and-assets-bootstrap in the planned chain.")1988 parser.add_argument("--run-selected-variants", action="store_true", help="Execute a small number of exploratory variants through the trusted execution helpers.")1989 parser.add_argument("--max-executed-variants", type=int, default=None, help="Maximum number of exploratory variants to execute when execution is enabled.")1990 parser.add_argument("--variant-timeout", type=int, default=None, help="Timeout in seconds for each executed exploratory variant.")1991 args = parser.parse_args()
344) -> Dict[str, Any]:345 if variant_spec.get("base_command") or not evaluation_source.get("command"):346 return variant_spec347348 normalized = dict(variant_spec)349 normalized["base_command"] = str(evaluation_source["command"]).strip()350 normalized["base_command_source"] = "evaluation_source"351 if evaluation_source.get("primary_metric") and not normalized.get("primary_metric"):
The “feasibility check” imports and executes repository Python top-level code
Source references: 7
What we found
Runtime smoke checks load candidate files with `exec_module`. A Python import is not a static syntax check: top-level statements execute. The final feasibility pass invokes these probes even when no candidate variant was actually run.
Why this matters
Malicious or merely side-effectful research code can modify files, make network calls, read environment variables, or perform expensive initialization during what may appear to be analysis. Silencing output does not prevent those effects.
This is not purely static analysis: it adds the target repository to Python's search path and loads candidate files through `exec_module`, which executes module-level statements and imports. Candidates are chosen heuristically from repository filenames, and the feasibility pass invokes these probes even before candidate runs. A selected file with import-time side effects could read or write files, launch processes, or use available credentials. Users can request AST/compile-only checks or require import probes to run in an isolated process with no network, minimal environment variables, and a read-only repository.
scripts/passes/execution_feasibility.py:247In the codeOpen original file
246247def import_probe_check(repo_path: Path, target_location_map: Sequence[Dict[str, Any]]) -> Dict[str, Any]:248 targets = safe_runtime_targets(target_location_map)249 if not targets:250 return {251 "name": "import-probe",252 "status": "passed",253 "passed": [],254 "blockers": [],255 "notes": ["no-safe-import-targets"],256 }257 passed: List[str] = []258 blockers: List[str] = []259 sys_path_added = False260 repo_root = str(repo_path)261 if repo_root not in sys.path:262 sys.path.insert(0, repo_root)263 sys_path_added = True264 try:265 for item in targets:266 rel = str(item.get("file") or "")267 module_path = repo_path / rel268 if not module_path.exists():269 blockers.append(f"missing:{rel}")270 continue271 module_name = f"_research_explore_smoke_{hashlib.sha1(rel.encode('utf-8')).hexdigest()[:12]}"272 try:273 spec = importlib.util.spec_from_file_location(module_name, module_path)274 if spec is None or spec.loader is None:275 blockers.append(f"import-spec:{rel}")276 continue277 module = importlib.util.module_from_spec(spec)278 exec_module_silenced(spec, module)279 passed.append(rel)280 except ModuleNotFoundError as exc:281 blockers.append(f"missing-dependency:{rel}:{exc.name or 'unknown'}")282 except Exception as exc: # pragma: no cover - defensive, exercised via repo fixtures283 blockers.append(f"import-error:{rel}:{exc.__class__.__name__}")284 finally:
Show 6 other places
scripts/passes/execution_feasibility.py:303In the codeOpen original file
302303def constructor_probe_check(repo_path: Path, target_location_map: Sequence[Dict[str, Any]]) -> Dict[str, Any]:304 targets = safe_runtime_targets(target_location_map)305 if not targets:306 return {307 "name": "constructor-probe",308 "status": "passed",309 "passed": [],310 "blockers": [],311 "notes": ["constructor-probe-not-applicable"],312 }313 passed: List[str] = []314 blockers: List[str] = []315 soft_notes: List[str] = []316 sys_path_added = False317 repo_root = str(repo_path)318 if repo_root not in sys.path:319 sys.path.insert(0, repo_root)320 sys_path_added = True321 try:322 for item in targets:323 rel = str(item.get("file") or "")324 target_symbol = str(item.get("target_symbol") or "")325 symbol_root = target_symbol326 if ":" in symbol_root:327 symbol_root = symbol_root.split(":", 1)[1]328 symbol_root = symbol_root.split(".", 1)[0].strip()329 if not symbol_root or symbol_root == "unspecified-symbol":330 soft_notes.append(f"unresolved-target-symbol:{rel}")331 continue332 module_path = repo_path / rel333 module_name = f"_research_explore_ctor_{hashlib.sha1(rel.encode('utf-8')).hexdigest()[:12]}"334 try:335 spec = importlib.util.spec_from_file_location(module_name, module_path)336 if spec is None or spec.loader is None:337 blockers.append(f"constructor-spec:{rel}")338 continue339 module = importlib.util.module_from_spec(spec)340 exec_module_silenced(spec, module)341 if hasattr(module, symbol_root):
explore-code/scripts/plan_code_changes.py:95In the codeOpen original file
9495def collect_candidate_edit_targets(repo: Path, current_research: str, task_family: str) -> List[str]:96 tokens = focus_tokens(current_research, task_family)97 scored: List[tuple[int, str]] = []98 for path in repo.rglob("*"):99 if path.is_dir():100 continue101 if any(part in SKIP_PARTS for part in path.relative_to(repo).parts):102 continue103 if path.suffix.lower() not in CODE_SUFFIXES:104 continue105 rel = path.relative_to(repo).as_posix()106 score = score_path(rel, task_family, tokens)107 if score:108 scored.append((score, rel))109110 scored.sort(key=lambda item: (-item[0], item[1]))111 return [rel for _, rel in scored[:8]]112
scripts/passes/execution_feasibility.py:259In the codeOpen original file
258 blockers: List[str] = []259 sys_path_added = False260 repo_root = str(repo_path)261 if repo_root not in sys.path:262 sys.path.insert(0, repo_root)263 sys_path_added = True264 try:265 for item in targets:266 rel = str(item.get("file") or "")267 module_path = repo_path / rel268 if not module_path.exists():269 blockers.append(f"missing:{rel}")270 continue271 module_name = f"_research_explore_smoke_{hashlib.sha1(rel.encode('utf-8')).hexdigest()[:12]}"272 try:273 spec = importlib.util.spec_from_file_location(module_name, module_path)274 if spec is None or spec.loader is None:275 blockers.append(f"import-spec:{rel}")276 continue277 module = importlib.util.module_from_spec(spec)278 exec_module_silenced(spec, module)279 passed.append(rel)280 except ModuleNotFoundError as exc:
The optional model runner executes commands locally without an OS sandbox
Source references: 2
What we found
The documentation says the model reads the README, selects steps, and observes execution, while expressly stating that execution is local and not a system sandbox. Although a task file pre-limits commands, approved commands still inherit the launcher process's local privileges.
Why this matters
If an approved command, dependency, or repository script is untrusted, it could read or alter files available to the account, use credentials present in the environment, or start network and child processes. A recorded command allowlist is not operating-system isolation.
This is an optional model-driven runner, but its active commands execute locally and the documentation explicitly says it is not a system sandbox. Although a pre-reviewed task file limits commands and acceptance criteria, allowed commands may still access files or consume resources with the launching process's permissions. Users can ask for the exact command allowlist and run it under a low-privilege account, container, or isolated workspace.
ai-research-reproduction/references/agent-runner.md:167In the instructionsOpen original file
The environment bootstrap executes repository-controlled dependency and build instructions
Source references: 4
What we found
The bootstrap selects an installation flow from a top-level `environment.yml`, `requirements.txt`, `pyproject.toml`, or `setup.py`. It runs Conda environment creation, pip requirements installation, or `pip install -e .`; these operations can execute repository build backends or downloaded package code.
Why this matters
A malicious repository or poisoned dependency can execute during installation, alter the new environment or user caches, access the network, and read files or credentials visible to the bootstrap process. A virtual environment isolates packages but is not a security sandbox.
This is supported, but only when the user actually runs the bootstrapper without `--dry-run`. It executes conda/mamba creation and pip installation based on files in the target repository; for `pyproject.toml` or `setup.py`, editable installation may invoke the repository's build backend. An untrusted repository could therefore execute code during installation or introduce malicious dependencies. Users can require pre-install confirmation, pinned dependencies, and an isolated executor.
env-and-assets-bootstrap/SKILL.md:51In the instructionsOpen original file
5051## Notes5253Use `references/env-policy.md`, `references/assets-policy.md`, `scripts/bootstrap_env.py`, `scripts/plan_setup.py`, and `scripts/prepare_assets.py`.54Use `scripts/bootstrap_env.sh` only as a POSIX wrapper around the Python bootstrapper when a shell entrypoint is more convenient.55
Show 3 other places
env-and-assets-bootstrap/scripts/bootstrap_env.py:23In the codeOpen original file
env-and-assets-bootstrap/scripts/bootstrap_env.py:114In the codeOpen original file
113114 if env_file and env_file.name in CONDA_ENV_FILES:115 if manager is None:116 raise SystemExit("A conda-compatible manager is required for environment.yml-based setup. Install conda or mamba first.")117118 create_command = [manager, "env", "create", "-f", rel_env_file]119 if not declared_env_name:120 create_command.extend(["-n", resolved_env_name])121 run_command(create_command, cwd=repo_path, dry_run=args.dry_run)122 print_activation_instructions(declared_env_name or resolved_env_name, using_conda=True)
Medium risk
Queue CPU, GPU, and memory budgets are admission declarations, not enforced process limits
Source references: 7
What we found
The queue decides whether to launch a job from its declared `resource_request`, but explicitly records the semantics as `request-based-admission-not-os-enforcement`. Jobs are then submitted as ordinary host subprocesses, with no shown cgroup, container, job-object, or GPU-quota enforcement.
Why this matters
A job that understates its needs or spikes in usage can exhaust host memory, monopolize a GPU, or disrupt other workloads; concurrent jobs amplify the effect. A timeout limits duration but cannot prevent rapid resource exhaustion.
This is supported. The queue only compares each job's declared resource request with scheduler budgets, and explicitly labels the policy as request-based admission rather than OS enforcement. Once admitted, the command is launched as a normal host subprocess. A job that understates its needs or grows during execution can therefore exhaust CPU, memory, or GPU resources and disrupt other user processes. Users can restrict concurrency and timeouts and require containers, cgroups, Windows Job Objects, or equivalent hard limits.
ai-research-reproduction/_bundled/shared/scripts/task_queue.py:193In the codeOpen original file
192193def _normalize_resources(value: Any) -> Dict[str, int]:194 resources = value if isinstance(value, dict) else {}195 result = {196 "cpu_slots": int(resources.get("cpu_slots", 1)),197 "gpu_slots": int(resources.get("gpu_slots", 0)),198 "memory_mib": int(resources.get("memory_mib", 0)),199 }200 if result["cpu_slots"] < 1 or result["gpu_slots"] < 0 or result["memory_mib"] < 0:201 raise ValueError("resource_request requires cpu_slots >= 1 and non-negative gpu_slots/memory_mib")202 return result203
Show 6 other places
ai-research-reproduction/_bundled/shared/scripts/task_queue.py:416In the codeOpen original file
415416def _fits(request: Dict[str, int], available: Dict[str, int]) -> bool:417 return all(request[key] <= available[key] for key in ("cpu_slots", "gpu_slots", "memory_mib"))418
ai-research-reproduction/_bundled/shared/scripts/task_queue.py:517In the codeOpen original file
ai-research-reproduction/_bundled/shared/scripts/task_queue.py:508In the codeOpen original file
507 for job in store.jobs():508 if job["status"] == "queued" and not _fits(job["resource_request"], totals):509 store.transition(510 job,511 "blocked",512 "resource-request-exceeds-budget",513 finished_at=utc_now(),514 scheduler_budget=totals,515 )516
ai-research-reproduction/_bundled/shared/scripts/task_queue.py:518In the codeOpen original file
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: 3
Medium risk
Run information is persisted in the user profile by default and can influence later projects
Source references: 6
What we found
Lesson recording is enabled by default. On partial or blocked reproduction runs, the orchestrator appends the blocker summary, documented command, and repository fingerprint to `~/.rigorpilot/lessons.jsonl`; the exploration Skill is then instructed to consult the generated `PERSONAL_RIGOR.md`. A credential-pattern filter exists, but its own comment says it is not a guarantee.
Why this matters
Research project names, path fragments, failure details, and command arguments can remain outside the expected output directory, appear in shared-account backups, and influence decisions for unrelated future projects. Secret formats not recognized by the regular expression may also be stored.
This is supported, with limited scope: recording occurs only when execution was requested and the result is partial/blocked, or when a prior failure is later resolved. Recording is enabled by default and appends a blocker summary, command detail, and repository fingerprint under the user's home directory. The exploration skill is told to consult the overlay later, so prior records may influence advice for other projects. Secret filtering is explicitly best-effort. Users can set `RIGORPILOT_LESSONS=0` and require preview or consent before persistence.
ai-research-reproduction/_bundled/shared/scripts/lessons_store.py:21In the codeOpen original file
20VALID_KINDS = {"failure-fix", "user-correction", "preference", "generalization"}21# Best-effort blocklist: keyword shapes plus common bare-credential formats.22# This is a guardrail, not a guarantee — callers still must not pass secrets.23SECRET_RE = re.compile(24 r"(api[_-]?key|secret|token|password|passwd|authorization|bearer\s+\S|-----BEGIN"25 r"|AKIA[0-9A-Z]{16}|ghp_[A-Za-z0-9]{20,}|gho_[A-Za-z0-9]{20,}|sk-[A-Za-z0-9_-]{16,}"26 r"|xox[a-z]-[A-Za-z0-9-]{10,}|AIza[0-9A-Za-z_-]{30,})",27 re.IGNORECASE,28)29MAX_FIELD_CHARS = 300
Show 5 other places
ai-research-reproduction/_bundled/shared/scripts/lessons_store.py:41In the codeOpen original file
ai-research-reproduction/scripts/orchestrate_repro.py:62In the codeOpen original file
61 try:62 if status in {"partial", "blocked"}:63 path = store.record_lesson(64 kind="failure-fix",65 skill="ai-research-reproduction",66 summary=f"[{status}] {context.get('main_blocker', 'unrecorded blocker')}",67 detail=str(context.get("documented_command") or ""),68 fingerprint=fingerprint,69 )70 return str(path) if path else None
ai-research-reproduction/_bundled/shared/scripts/lessons_store.py:125In the codeOpen original file
124 }125 path = lessons_path()126 path.parent.mkdir(parents=True, exist_ok=True)127 with path.open("a", encoding="utf-8") as handle:128 handle.write(json.dumps(entry, ensure_ascii=False) + "\n")129 return path130
ai-research-reproduction/scripts/orchestrate_repro.py:54In the codeOpen original file
5354def maybe_record_lesson(repo_path: Path, context: Dict[str, Any]) -> Optional[str]:55 """Record failure blockers and later resolutions per the continuous-learning policy."""56 store = load_lessons_store()57 if store is None or not store.lessons_enabled():58 return None59 fingerprint = store.repo_fingerprint(repo_path)60 status = context.get("status")61 try:62 if status in {"partial", "blocked"}:63 path = store.record_lesson(64 kind="failure-fix",65 skill="ai-research-reproduction",66 summary=f"[{status}] {context.get('main_blocker', 'unrecorded blocker')}",67 detail=str(context.get("documented_command") or ""),68 fingerprint=fingerprint,69 )70 return str(path) if path else None71 if status == "success":
117 details.118- Load `../ai-research-reproduction/references/research-thinking-loop.md` before proposing or ranking candidate changes; it is the required greedy observe-ground-design-compare cycle.119- Load `../ai-research-reproduction/references/research-rigor-principles.md` before making novelty, contribution, SOTA, or comparability statements.120- Consult `~/.rigorpilot/PERSONAL_RIGOR.md` if present, under `../ai-research-reproduction/references/continuous-learning-policy.md` (advisory only; core wins).121- Load `../ai-research-reproduction/references/deep-learning-experiment-principles.md` when training,
Medium risk
Repository-discovered URLs are resolved and may be contacted by default
Source references: 6
What we found
Repository locator extraction defaults to enabled, and every extracted record is passed to GitHub, arXiv, DOI, or generic-URL providers. Provider results are explicitly marked `network-fetched`.
Why this matters
Opening an untrusted repository can make the machine contact author-supplied external or internal addresses, exposing request timing, source IP, and the requested URL, and potentially reaching services visible only from the user's network. The shown evidence does not establish that credentials are sent.
Repository-local locator extraction is enabled by default, and extracted values are resolved alongside other seeds. Recognized GitHub, arXiv, DOI, and generic URLs are dispatched to provider resolvers; successful provider results are explicitly marked `network-fetched`. Thus, recognizable URLs in repository text may cause requests that reveal timing and source IP, and could target internal URLs. Users can disable `enable_repo_local_extraction`, deny network access, or require an allowlist plus private-network address blocking.
83 locators = _extract_locators(text)84 relative_path = path.relative_to(repo_root).as_posix()85 for locator in locators:86 if locator in seen_locators:87 continue88 seen_locators.add(locator)89 seeds.append(90 {91 "kind": _classify_kind(locator),92 "title": locator,93 "summary": f"Repo-local extracted source from `{relative_path}`.",94 "query": locator,95 "source_url": locator if locator.lower().startswith("http") else "",96 "source_repo": "",97 "source_file": "",98 "source_symbol": "",99 "origin": "repo_local_extracted",100 "raw_locator": locator,101 "extracted_from_repo_paths": [relative_path],102 }
scripts/lookup/providers/github_provider.py:73In the codeOpen original file
72 "summary": str(payload.get("description") or ""),73 "url": str(payload.get("html_url") or record["url"]),74 "repo_full_name": str(payload.get("full_name") or repo_full_name),75 "parse_status": "resolved",76 "fetch_status": "network-fetched",77 "evidence_class": "external_provider",78 "provider_metadata": {
Medium risk
Model requests and persistent traces may contain private research or repository content
Source references: 3
What we found
The runner transmits requests over HTTP to the selected model service and locally stores messages, requests, responses, tool activity, and results. Its own documentation warns against publishing private-repository traces without review.
Why this matters
When a remote model is enabled, task or README material supplied to the model leaves the machine. The local trace also creates a sensitive copy of research context and actions; sharing the output directory or publishing traces can disclose it further.
The documentation supports both model HTTP requests and detailed local persistence: state stores messages and results, while traces store requests, responses, and tool activity. It explicitly warns that private-repository traces must be reviewed before publication. Thus, private code or research data present in prompts, tool output, or responses may enter model requests or local traces. Users should confirm the model provider, retention policy, and trace location, and restrict sensitive context and trace publication.
ai-research-reproduction/references/agent-runner.md:115In the instructionsOpen original file
114115Optional `parameters` are transmitted, not just recorded: the current transport116supports `temperature` or `top_p` (not both), and `stop_sequences`. Unsupported117fields are rejected before HTTP; `max_tokens` remains controlled by the task118budget. Leave sampling settings absent unless the selected model supports them:119the [Messages API](https://platform.claude.com/docs/en/api/messages/create)120deprecates these controls for newer models. A local protocol test is not a121compatibility claim for every model or gateway.122
Show 2 other places
ai-research-reproduction/references/agent-runner.md:125In the instructionsOpen original file
124125The standard README bundle is accompanied by `agent_state.json` (task/model126identity, messages, plan, pending calls, results), `trajectory.jsonl` (requests,127responses, public reasons, tools and usage), and `_runtime/` process evidence.128The verifier requires all `required_commands` to pass their exit/stdout and any
ai-research-reproduction/references/agent-runner.md:161In the instructionsOpen original file
160gateway token accounting may differ. Output size is checked between actions,161not an OS disk quota. `CANCEL` is checked between actions; use the runtime CANCEL162file to stop an active process. Credentials are not included in provider errors.163Do not publish traces from private repositories without reviewing their contents.164
Could it delete files or keep running?Looks for broad file deletion, disk overwrites, and programs set to start automatically.Risks found: 3
Low risk
Initialization creates a hidden sibling worktree and a new Git branch
Source references: 3
What we found
The worktree location is placed under the Git root's parent directory. If the branch does not exist, the orchestrator uses `git worktree add -b` to create both the branch and full worktree before the main scan and planning stages.
Why this matters
A new branch, worktree, and hidden directory remain on disk. Large repositories may consume significant space and the added worktree can affect later branch management or cleanup.
The orchestrator places its worktree in a hidden directory beside the Git root. If the experiment branch does not exist, it runs `git worktree add -b`, creating both a branch and a full worktree from the current HEAD. This is an intended isolation mechanism, but it still creates persistent files and Git references outside the requested output directory and may consume substantial disk space. Users can confirm the location and cleanup policy first or require use of an explicitly supplied existing isolated branch.
20182019 durable_current_research = validate_current_research(repo_path, current_research)2020 experiment_branch = choose_experiment_branch(current_research, args.experiment_branch)2021 workspace_info = ensure_experiment_workspace(repo_path, experiment_branch)2022 context_id = build_context_id(current_research, experiment_branch)2023 workspace_repo_path = Path(workspace_info["workspace_root"]).resolve()20242025 helper_stage_trace = [2026 build_stage_trace_entry("validate-current-research", "ai-research-explore/validate_current_research", f"Validated durable current research `{current_research}` as `{durable_current_research['kind']}`."),2027 build_stage_trace_entry("workspace", "ai-research-explore/ensure_experiment_workspace", f"{'Created' if workspace_info['created_branch'] else 'Validated'} isolated {workspace_info['mode']} for branch `{experiment_branch}` at `{workspace_info['workspace_root']}`."),2028 ]20292030 scan_data = run_json(scan_script, ["--repo", str(workspace_repo_path), "--json"])2031 helper_stage_trace.append(build_stage_trace_entry("repo-scan", "repo-intake-and-plan/scripts/scan_repo.py", f"Scanned repository structure and README signals for `{repo_path.name}`."))
Low risk
An optional flag writes a persistent file beside the source README
Source references: 2
What we found
With source-adjacent-readme enabled, the tool creates RIGORPILOT_README.md in the original README directory instead of keeping all material in the dedicated output directory. The documentation says conflicting files are not overwritten.
Why this matters
The source repository gains a file that Git may detect, a user may accidentally commit, or another tool may consume. A repeat run may refresh an unchanged tool-owned copy.
Legitimate use of this code
Writing beside the source README is an explicitly optional feature that occurs only when `--source-adjacent-readme` is supplied. The file is an annotated copy preserving the original content; ordinary evidence remains in the output directory, conflicting or unrelated files are not overwritten, and the original README stays intact. Users who do not want an extra source-directory file can omit the flag and ask to confirm the reported destination.
This assessment concerns the code and conditions shown, not proof that harm has occurred.
ai-research-reproduction/references/output-spec.md:176In the instructionsOpen original file
175176## Optional source-adjacent README177178Add `--source-adjacent-readme` to `orchestrate_repro.py` or `run_agent.py` to179also create `RIGORPILOT_README.md` in the original README's directory. Keep180the standard `repro_outputs/ANNOTATED_README.md` and its evidence files.181
Show 1 other places
ai-research-reproduction/references/output-spec.md:189In the instructionsOpen original file
188189The bundle retains `readme_delivery.json` to identify its generated copy.190Repeating with the same source and output may refresh an unchanged owned copy.191An unrelated or edited file, symlink, hard link, or conflicting receipt is not192overwritten. Keep the receipt with the evidence; do not use it to claim that193source code or external media were verified. The original README remains intact.194
Low risk
Failed and later-resolved runs are recorded as durable lessons by default
Source references: 1
What we found
The skill states that failed and subsequently resolved runs are automatically recorded through lessons_store.py unless RIGORPILOT_LESSONS=0 is set.
Why this matters
This creates an additional persistent record outside the immediate campaign artifacts. It may contain project failure or research-process information and may influence later runs that consume those lessons. The supplied lines do not show its stored fields or retention period.
What this evidence establishes
The entrypoint does say failed and later-resolved runs are recorded as lessons by default and provides an opt-out variable. However, the supplied source does not show the recorded fields, storage location, retention period, or any external transmission, so the concrete privacy or account impact of “long-term experience” cannot be established. Users can set `RIGORPILOT_LESSONS=0` before running and ask the author what is stored, where, and how it is removed.
This assessment concerns the code and conditions shown, not proof that harm has occurred.
ai-research-reproduction/SKILL.md:123In the instructionsOpen original file
122- Load `references/deep-learning-experiment-principles.md` when dataset, split, metric, checkpoint, training, or evaluation details matter.123- Consult `~/.rigorpilot/PERSONAL_RIGOR.md` if present, under `references/continuous-learning-policy.md` (advisory only; core wins).124- Failed and later-resolved runs are auto-recorded as lessons via `shared/scripts/lessons_store.py` (`RIGORPILOT_LESSONS=0` disables).125- Load `references/research-safety-principles.md` before protocol-sensitive
Could it bypass safety checks?Looks for skipped website security checks, excessive file access, or actions that skip your approval.Risks found: 1
Medium risk
Generic source resolution can request arbitrary HTTP(S) locations without shown private-network or response-size controls
Source references: 5
What we found
Source extraction collects URLs from repository text, and the generic URL provider passes a normalized address directly to `urlopen`. The shown code has no host allowlist and no rejection of loopback, link-local, or private networks; `response.read()` also has no byte limit.
Why this matters
A URL planted in a repository or campaign can make the host contact an internal administration endpoint, cloud metadata service, or local service, creating an SSRF path. A large response can also pressure memory. The supplied lines do not establish external exfiltration, but internal responses enter the local research-record processing chain.
This is supported when source lookup resolves URLs extracted from repository files. The extractor accepts arbitrary HTTP(S) URLs, and the generic provider fetches the resulting URL directly. The visible transport code has no host/IP-range validation and calls `response.read()` without a byte limit. A malicious repository could induce requests to localhost, private networks, or cloud metadata services, or return a large response that consumes memory. Users can require an allowlist, private/loopback/link-local blocking, and a response-size cap.
5051def _extract_locators(text: str) -> List[str]:52 found: List[str] = []53 for url in extract_urls(text):54 if url not in found:55 found.append(url)56 for pattern in (ARXIV_ID_RE, DOI_RE):57 for match in pattern.finditer(text):58 raw = match.group(0).strip()59 if raw and raw not in found:60 found.append(raw)61 return found62
Show 4 other places
scripts/lookup/providers/url_provider.py:13In the codeOpen original file
1213def resolve_url_record(locator_info: Dict[str, Any]) -> Dict[str, Any]:14 url = canonicalize_url(locator_info.get("url") or locator_info.get("raw_locator") or "")15 parsed = urllib.parse.urlsplit(url) if url else None16 record = {17 "provider_type": "url",18 "source_type": "web",19 "locator_type": locator_info.get("locator_type", "url"),20 "raw_locator": locator_info.get("raw_locator", ""),21 "normalized_id": locator_info.get("normalized_id", f"url:{url}" if url else ""),22 "title": url,23 "url": url,24 "authors": [],25 "year": None,26 "venue": parsed.netloc if parsed else "",27 "repo_full_name": "",28 "doi": "",29 "arxiv_id": "",30 "parse_status": "parsed-only",31 "fetch_status": "parsed-only",32 "evidence_class": "parsed_locator",33 "provider_metadata": {"resolved_via": "url", "host": parsed.netloc.lower() if parsed else ""},34 }35 if not url:36 return record37 try:38 payload = http_get(url, accept="text/html, application/xhtml+xml;q=0.9")39 parser = MetadataHTMLParser()40 parser.feed(payload.decode("utf-8", errors="ignore"))41 canonical = parser.canonical_url() or url
6364def extract_urls(text: str) -> list[str]:65 found: list[str] = []66 for match in URL_RE.finditer(str(text or "")):67 url = match.group(0).rstrip(".,);]")68 if url not in found:69 found.append(url)70 return found71
scripts/lookup/providers/url_provider.py:35In the codeOpen original file
34 }35 if not url:36 return record37 try:38 payload = http_get(url, accept="text/html, application/xhtml+xml;q=0.9")39 parser = MetadataHTMLParser()40 parser.feed(payload.decode("utf-8", errors="ignore"))41 canonical = parser.canonical_url() or url
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.Risks found: 2
Medium risk
Run ranking can use the last arbitrary non-loss metric when the primary metric is missing
Source references: 4
What we found
The training log parser designates the last non-loss/error metric as `best_metric` without comparing which value is actually best. If the primary metric is absent, ranking explicitly falls back to that value.
Why this matters
Logs containing several metrics, or merely changing metric order, can cause the wrong measurement to select the “best” candidate and misdirect compute spending, research direction, or SOTA comparisons.
Training-log parsing does not calculate the true best value across steps. It excludes names containing terms such as loss/error and then selects the last inserted non-loss metric; if only loss-like metrics exist, it selects the last metric or validation loss. When the configured primary metric is unavailable, ranking falls back to this `best_metric`. An unrelated log metric could therefore affect candidate ordering and subsequent trial recommendations. Users can require an exact primary-metric match, make unmatched runs unrankable, and specify metric direction and aggregation.
9697 priority_names = [98 name for name in observed_metrics99 if not any(token in name.lower() for token in {"loss", "error", "rmse", "mae", "wer", "cer"})100 ]101 if priority_names:102 chosen = priority_names[-1]103 best_metric = {"name": chosen, "value": observed_metrics[chosen]}104 elif observed_metrics:105 validation_losses = [name for name in observed_metrics if name.lower() in {"val_loss", "validation_loss", "valid_loss"}]106 chosen = validation_losses[-1] if validation_losses else list(observed_metrics)[-1]107 best_metric = {"name": chosen, "value": observed_metrics[chosen]}108
ai-research-reproduction/references/explore-variant-spec.md:150In the instructionsOpen original file
149150## Notes151152- Keep `current_research` durable and auditable.153- In campaign mode, pair `variant_spec` with a frozen task family, dataset, evaluation source, and provided SOTA table.154- Keep exploratory output candidate-only.155- Do not treat pre-execution ranking scores as trusted scientific conclusions.156- If `primary_metric` is omitted, downstream ranking falls back to parsed `best_metric`.157
Low risk
Pre-execution “predicted success/gain” scores are fixed formulas, not model or dataset evidence
Source references: 6
What we found
Success decreases with axis aggressiveness, steps, and subset size, while expected gain increases from the same factors; the resulting synthetic scores directly order candidates. The formula uses no historical run results or task-specific evidence.
Why this matters
Users may mistake fields named `predicted_success_score` and `predicted_gain_score` for validated predictions, prioritize unsuitable candidates, and waste compute.
Legitimate use of this code
The stated formulas and their use in ordering are real, but both code and documentation frame them as pre-execution heuristic prioritization—not model predictions, historical estimates, or scientific evidence. Post-execution ranking separately uses status and observed metrics. The main concern is that users could overread the `predicted_*` names; the supplied context explicitly explains the scores and their limitations, so this is not supported as concealed or falsely represented evidence. Users can still ask that the UI label them “heuristic” and review weights before allocating compute.
This assessment concerns the code and conditions shown, not proof that harm has occurred.
ai-research-reproduction/references/explore-variant-spec.md:90In the instructionsOpen original file
8990Interpretation:9192- `cost`93 Lower runtime and smaller subsets are cheaper.94- `success_rate`95 Lighter, less aggressive candidates are more likely to run cleanly.96- `expected_gain`97 Candidates that move farther from the current setting are treated as having higher upside.9899The weights are normalized before scoring. This stage is heuristic and should be treated as exploratory prioritization, not scientific proof.100
250 },251 "selection_policy": {252 "factors": ["cost", "success_rate", "expected_gain"],253 "weights": normalize_weights(spec),254 "scores": {255 "cost_score": "Lower is cheaper; derived from steps, subset size, and axis aggressiveness.",256 "cost_efficiency_score": "Higher is cheaper after inverting cost_score.",257 "predicted_success_score": "Higher means the candidate is more likely to run cleanly.",258 "predicted_gain_score": "Higher means the candidate is more likely to produce a measurable improvement.",259 "total_score": "Weighted composite used for pre-execution candidate ranking.",260 },261 },
ai-research-reproduction/references/explore-variant-spec.md:99In the instructionsOpen original file
9899The weights are normalized before scoring. This stage is heuristic and should be treated as exploratory prioritization, not scientific proof.100101### Post-execution result ranking102103After candidates actually run, downstream ranking should use real execution evidence:104105- `status` first106- then `primary_metric`107- then `metric_goal`108
Inside this skill
7 instruction sections
The Skill plans or runs candidate research only after explicit authorization and a durable `current_research` anchor; its instructions freeze the dataset, evaluation, SOTA reference, and budget and label results as exploratory evidence.
2728Use this skill only when the request has both:2930- Explicit exploration authorization such as candidate-only work, isolated31 branch or worktree, sweep, several variants, or exploratory ranking.32- A durable `current_research` context such as a branch, commit, checkpoint,33 run record, or already-trained local model state.34
55561. Confirm `current_research` and explicit explore-lane authorization.572. Accept either legacy `variant_spec` or higher-level `research_campaign`.583. In campaign mode, freeze the task, dataset, benchmark, evaluation source,59 SOTA reference, and budget before candidate work.604. Build only the repo-understanding artifacts needed for the current campaign,
72 requires real execution evidence.739. Write candidate-only outputs to `analysis_outputs/`, `sources/`, and74 `explore_outputs/` as appropriate; never present exploratory gains as trusted75 reproduction success. Include `SCIENTIFIC_CHANGELOG.md` and76 `COMPARABILITY_REPORT.md` for candidate scientific meaning and comparison77 boundaries.78
The bundled runtime launches a child process in the selected repository and persists full stdout, stderr, resource samples, state, and events in a per-run directory. On timeout or cancellation, it terminates the process group.
View source
ai-research-reproduction/_bundled/shared/scripts/runtime_runner.py:480In the codeOpen original file
ai-research-reproduction/_bundled/shared/scripts/runtime_runner.py:555In the codeOpen original file
554 now = time.monotonic()555 if cancel_path.exists():556 cancelled = True557 journal.event("cancel_detected", source="CANCEL")558 _terminate_process_tree(process, journal)559 break560 if timeout >= 0 and now - started_monotonic >= timeout:561 timed_out = True562 journal.event("timeout_detected", timeout_seconds=timeout)563 _terminate_process_tree(process, journal)564 break565 if now >= next_heartbeat:
Research-source resolution can contact arXiv, DOI, GitHub, and generic web pages. The shared transport has a six-second timeout, but the shown implementation places no size limit on the response body.
The companion reproduction flow enables a cross-run personal lesson store by default: blocker information and command summaries can be written to `~/.rigorpilot/lessons.jsonl` and later distilled into `PERSONAL_RIGOR.md` for Skill use; an environment variable can disable it.
View source
ai-research-reproduction/_bundled/shared/scripts/lessons_store.py:41In the codeOpen original file
119- Load `../ai-research-reproduction/references/research-rigor-principles.md` before making novelty, contribution, SOTA, or comparability statements.120- Consult `~/.rigorpilot/PERSONAL_RIGOR.md` if present, under `../ai-research-reproduction/references/continuous-learning-policy.md` (advisory only; core wins).121- Load `../ai-research-reproduction/references/deep-learning-experiment-principles.md` when training,
The Skill is intended for explicitly authorized candidate exploration with a durable `current_research` baseline; its description explicitly rejects treating candidate results as verified novelty or trusted reproduction.
910Use this as the Rigor Explore compatible skill slug after the researcher11explicitly authorizes candidate-only work on top of a durable12`current_research` anchor. The installed slug remains `ai-research-explore` for13compatibility. Rigor Explore is for meaningful and potentially novel deep14learning research candidates while preserving scientific rigor, comparability,15reproducibility, and auditable collaboration. Novelty and significance remain16hypotheses before literature contrast, ablation evidence, and fair comparison.17The skill does not promise autonomous discovery, global benchmark completeness,18novelty proof, or trusted reproduction success.19
2728Use this skill only when the request has both:2930- Explicit exploration authorization such as candidate-only work, isolated31 branch or worktree, sweep, several variants, or exploratory ranking.32- A durable `current_research` context such as a branch, commit, checkpoint,33 run record, or already-trained local model state.34
The orchestrator creates or reuses an isolated Git branch/worktree and writes analysis, source-cache, and exploration artifacts into several output directories.
Candidate variant execution is controlled by an execution policy and suppressed by an abandoned baseline, a human checkpoint, or a blocked manifest; baseline evaluation is nevertheless executed separately and automatically in campaign mode.
2306 short_run_runtime_seconds = 0.02307 should_run_variants = bool(campaign["execution_policy"]["run_selected_variants"])2308 if not compatibility_mode and baseline_gate.get("decision") == "abandon":2309 should_run_variants = False2310 if not compatibility_mode and checkpoint_state != "not-required":2311 should_run_variants = False2312 if experiment_manifest.get("status") == "blocked":2313 should_run_variants = False23142315 if should_run_variants:2316 if variant_matrix.get("base_command") and variant_matrix.get("variants"):
Source lookup extracts locators from repository files by default, attempts external-provider resolution, and persists resolved records under `sources/records` plus an index.
The skill is intended to start only after the researcher explicitly authorizes candidate exploration and supplies a durable current_research baseline such as a branch, commit, checkpoint, or trained state.
2728Use this skill only when the request has both:2930- Explicit exploration authorization such as candidate-only work, isolated31 branch or worktree, sweep, several variants, or exploratory ranking.32- A durable `current_research` context such as a branch, commit, checkpoint,33 run record, or already-trained local model state.34
The workflow makes or runs one bounded candidate, smoke-checks it, collects evidence, and ranks it against the current baseline; it is instructed to stop at blockers, exhausted budget, or a human checkpoint.
4243- Outer loop: understand the repository, freeze task/dataset/evaluation/budget,44 preserve user ideas, map sources, gate ideas, and decide whether the next45 experiment is worth running.46- Inner loop: make one bounded candidate change or run, smoke-check it, collect47 evidence, rank it against the current anchor, and either stop or return to the48 outer loop with the new evidence.4950This rhythm is a guide, not a rigid autonomous loop. Stop at explicit blockers,51unclear scientific meaning, exhausted budget, missing anchor/evaluation, or a52human checkpoint.53
Campaign mode generates research maps, scores, plans, run ledgers, and status records under analysis_outputs, sources, and explore_outputs; a minimal campaign should create only artifacts justified by the active work.
View source
references/research-campaign-spec.md:287In the instructionsOpen original file
286287## Output Expectations288289The following artifacts are the full advanced campaign surface. A minimal290campaign should produce only the files justified by the active work; do not291inflate the run with empty artifacts just to satisfy this list.292293Campaign mode writes:294
references/research-campaign-spec.md:295In the instructionsOpen original file
The accompanying model runner retains detailed evidence including messages, requests, responses, tool activity, usage, and process logs, and explicitly warns that traces from private repositories require review before publication.
View source
ai-research-reproduction/references/agent-runner.md:125In the instructionsOpen original file
124125The standard README bundle is accompanied by `agent_state.json` (task/model126identity, messages, plan, pending calls, results), `trajectory.jsonl` (requests,127responses, public reasons, tools and usage), and `_runtime/` process evidence.128The verifier requires all `required_commands` to pass their exit/stdout and any
ai-research-reproduction/references/agent-runner.md:161In the instructionsOpen original file
160gateway token accounting may differ. Output size is checked between actions,161not an OS disk quota. `CANCEL` is checked between actions; use the runtime CANCEL162file to stop an active process. Credentials are not included in provider errors.163Do not publish traces from private repositories without reviewing their contents.164
Start here · InstructionsSKILL.md
ai-research-explore
Lines connect the instruction file to its sections, not an observed execution order. Select a section to read the source.
File reference map
References: 40
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 records79 files
Coverage and gaps
Some results did not pass evidence validation or finish processing. This report does not represent a complete check.
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
env-and-assets-bootstrap/scripts/bootstrap_env.pyFull text included
env-and-assets-bootstrap/scripts/bootstrap_env.shFull text included
env-and-assets-bootstrap/scripts/plan_setup.pyFull text included
env-and-assets-bootstrap/scripts/prepare_assets.pyFull text included
explore-code/scripts/plan_code_changes.pyFull text included
explore-code/scripts/write_outputs.pyFull text included
explore-run/scripts/plan_variants.pyFull text included
explore-run/scripts/write_outputs.pyFull text included
minimal-run-and-audit/scripts/run_command.pyFull text included
minimal-run-and-audit/scripts/write_outputs.pyFull text included
run-train/scripts/run_training.pyFull text included
run-train/scripts/write_outputs.pyFull text included
scripts/lookup/__init__.pyFull text included
scripts/lookup/cache_store.pyFull text included
scripts/lookup/inventory_writer.pyFull text included
scripts/lookup/normalizers.pyFull text included
scripts/lookup/providers/__init__.pyFull text included
scripts/lookup/providers/arxiv_provider.pyFull text included
scripts/lookup/providers/base.pyFull text included
scripts/lookup/providers/doi_provider.pyFull text included
scripts/lookup/providers/github_provider.pyFull text included
scripts/lookup/providers/optional_provider.pyFull text included
scripts/lookup/providers/url_provider.pyFull text included
scripts/lookup/record_schema.pyFull text included
scripts/lookup/repo_extractors.pyFull text included
scripts/lookup/source_support.pyFull text included
scripts/orchestrate_explore.pyFull text included
scripts/passes/__init__.pyFull text included
scripts/passes/atomic_idea_decomposition.pyFull text included
scripts/passes/candidate_idea_generation.pyFull text included
scripts/passes/execution_feasibility.pyFull text included
scripts/passes/idea_cards.pyFull text included
scripts/passes/idea_ranking.pyFull text included
scripts/passes/implementation_fidelity.pyFull text included
scripts/passes/improvement_bank.pyFull text included
scripts/passes/lookup_sources.pyFull text included
scripts/passes/source_mapping.pyFull text included
scripts/write_outputs.pyFull text included
references/ai-research-explore-policy.mdFull text included
references/research-campaign-spec.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/explore-variant-spec.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-pitfall-checklist.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
analyze-project/references/analysis-policy.mdFull text included
env-and-assets-bootstrap/references/assets-policy.mdFull text included
env-and-assets-bootstrap/references/env-policy.mdFull text included
explore-code/references/explore-policy.mdFull text included
explore-run/references/execution-policy.mdFull text included
minimal-run-and-audit/references/reporting-policy.mdFull text included
repo-intake-and-plan/references/repo-scan-rules.mdFull text included
run-train/references/training-policy.mdFull text included
ai-research-reproduction/SKILL.mdFull text included
analyze-project/SKILL.mdFull text included
env-and-assets-bootstrap/SKILL.mdFull text included
explore-code/SKILL.mdFull text included
explore-run/SKILL.mdFull text included
minimal-run-and-audit/SKILL.mdFull text included
repo-intake-and-plan/SKILL.mdFull text included
run-train/SKILL.mdFull text included
agents/openai.yamlFull text included
references/idea-evaluation-framework.mdFull text included
references/smoke-validation-policy.mdFull text included
references/source-mapping-policy.mdFull text included
references/sources-naming-policy.mdFull 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.