Configuration¶
ResearchLoop is configured via a researchloop.toml file. The config file is searched in this order:
- Explicit path via
--config/-cCLI flag researchloop.tomlin the current working directory~/.config/researchloop/researchloop.toml
Complete reference¶
# ── Top-level settings ──────────────────────────────────────────
db_path = "researchloop.db" # SQLite database location
artifact_dir = "artifacts" # Local directory for uploaded artifacts
shared_secret = "your-secret" # Auth token for runner-to-orchestrator communication
orchestrator_url = "https://example.com" # Public URL where runners send webhooks
claude_command = "" # Override the claude command globally
# Global context included in all sprints (all studies, all clusters)
context = "Always use Python 3.10+ features."
context_paths = ["./global-context.md"] # Files whose contents are included as context
# ── Cluster configuration ───────────────────────────────────────
[[cluster]]
name = "hpc" # Unique cluster identifier
host = "login.cluster.example.com" # SSH hostname
port = 22 # SSH port
user = "researcher" # SSH username
key_path = "~/.ssh/id_ed25519" # Path to SSH private key
scheduler_type = "slurm" # "slurm", "sge", or "local"
working_dir = "/scratch/user/researchloop" # Base directory on the cluster
max_concurrent_jobs = 4 # Max simultaneous jobs on this cluster
claude_command = "claude --dangerously-skip-permissions" # Claude CLI command
# Cluster-specific context (appended after global context)
context = "GPUs are NVIDIA L40. Check CUDA_VISIBLE_DEVICES before running."
context_paths = ["./cluster-notes.md"]
# Environment variables injected into job scripts
[cluster.environment]
# ANTHROPIC_API_KEY = "sk-ant-..." # Only needed if not using claude login
# SLURM/SGE job options (passed as #SBATCH or #$ directives)
[cluster.job_options]
gres = "gpu:l40:1"
cpus-per-task = "8"
mem = "64G"
# ── Study configuration ─────────────────────────────────────────
[[study]]
name = "my-study" # Unique study identifier
cluster = "hpc" # Must match a [[cluster]] name
description = "Research into X" # Human-readable description
# Study context (appended after global + cluster context)
claude_md_path = "./studies/my-study/CLAUDE.md" # File with study-specific context
context = """
Focus on improving F1 score. Use batch size 1024.
"""
# Sprint settings
sprints_dir = "/scratch/user/my-study" # Where sprint dirs are created
# Default: <working_dir>/<study_name>
max_sprint_duration_hours = 8 # SLURM --time limit
red_team_max_rounds = 3 # Number of red-team/fix cycles
allow_loop = true # Whether auto-loops are allowed
# Override claude command for this study
claude_command = ""
# Per-study SLURM/SGE overrides (merged with cluster.job_options)
[study.job_options]
gres = "gpu:a100:2"
# ── Notifications ────────────────────────────────────────────────
[ntfy]
url = "https://ntfy.sh" # ntfy server URL (default: ntfy.sh)
topic = "researchloop" # ntfy topic for push notifications
[slack]
bot_token = "" # Slack Bot User OAuth Token (xoxb-...)
signing_secret = "" # Slack Signing Secret
channel_id = "C0123456789" # Channel or user ID for notifications
allowed_user_ids = ["U0123456789"] # Users allowed to interact with bot
restrict_to_channel = false # If true, only respond in channel_id
# (DMs are always allowed)
# ── Dashboard ────────────────────────────────────────────────────
[dashboard]
enabled = true # Enable the web dashboard
host = "0.0.0.0" # Bind address
port = 8080 # Bind port
password_hash = "" # bcrypt hash (prefer env var or setup page)
Context hierarchy¶
Context is assembled from multiple sources and concatenated in this order:
- Global context --
contextand files fromcontext_pathsat the top level - Cluster context --
contextand files fromcontext_pathson the cluster - Study context --
contextinline text and the file atclaude_md_path
The combined context is:
- Included in all sprint research prompts
- Written as CLAUDE.md to the sprint directory on the cluster (so Claude CLI picks it up automatically)
- Used by the auto-loop idea generator
Environment variable overrides¶
All secrets and sensitive settings can be set via environment variables with the RESEARCHLOOP_ prefix. Environment variables take precedence over TOML values.
| Environment variable | Overrides |
|---|---|
RESEARCHLOOP_SHARED_SECRET |
shared_secret |
RESEARCHLOOP_ORCHESTRATOR_URL |
orchestrator_url |
RESEARCHLOOP_DB_PATH |
db_path |
RESEARCHLOOP_ARTIFACT_DIR |
artifact_dir |
RESEARCHLOOP_SLACK_BOT_TOKEN |
slack.bot_token |
RESEARCHLOOP_SLACK_SIGNING_SECRET |
slack.signing_secret |
RESEARCHLOOP_SLACK_CHANNEL_ID |
slack.channel_id |
RESEARCHLOOP_SLACK_ALLOWED_USER_IDS |
slack.allowed_user_ids (comma-separated) |
RESEARCHLOOP_NTFY_TOPIC |
ntfy.topic |
RESEARCHLOOP_NTFY_URL |
ntfy.url |
RESEARCHLOOP_DASHBOARD_PASSWORD |
Auto-hashed with bcrypt on startup |
RESEARCHLOOP_DASHBOARD_PASSWORD_HASH |
dashboard.password_hash |
RESEARCHLOOP_DASHBOARD_PORT |
dashboard.port |
RESEARCHLOOP_DASHBOARD_HOST |
dashboard.host |
Recommended approach
Keep your researchloop.toml with only structural config (clusters, studies, context). Put secrets in environment variables or your deployment platform's secret manager.
Study CLAUDE.md¶
Each study can have a CLAUDE.md file that provides domain-specific context to Claude. This file is included in every sprint's research prompt and written to the sprint directory on the cluster.
Scaffold a starter file:
This creates studies/my-study/CLAUDE.md with sections for:
- Overview -- what you're studying
- Background -- key papers, prior findings, domain knowledge
- Codebase -- existing code, data formats, infrastructure
- Goals -- what you're trying to learn or build
- Constraints -- rules for the sprints to follow
Job options¶
Job options are merged from three levels (later values override earlier):
cluster.job_options-- defaults for all studies on this clusterstudy.job_options-- overrides for a specific study- Per-sprint overrides -- from the dashboard form or API request
Common SLURM options:
| Option | Example | Description |
|---|---|---|
gres |
gpu:l40:1 |
GPU resources |
mem |
64G |
Memory limit |
cpus-per-task |
8 |
CPU cores |
partition |
gpu |
SLURM partition |
qos |
high |
Quality of service |