Running the scheduler¶
The scheduler is the long-running process that keeps the evolution pipeline moving: it ingests completed jobs, samples new work from the MAP-Elites archive, and dispatches jobs to the Dramatiq worker queue.
Start¶
Recommended usage with uv:
uv run loreley scheduler # continuous loop
uv run loreley scheduler --once # single tick (cron / smoke tests)
uv run loreley scheduler --yes --once # non-interactive run
Minimum required settings for a functional scheduler are:
EXPERIMENT_IDMAPELITES_EXPERIMENT_ROOT_COMMITMAPELITES_CODE_EMBEDDING_DIMENSIONSSCHEDULER_MAX_TOTAL_JOBS
You also need database and Redis connectivity (DATABASE_URL, TASKS_REDIS_URL), and a writable repository checkout (SCHEDULER_REPO_ROOT, or it falls back to WORKER_REPO_WORKTREE / the current directory).
When the scheduler shares WORKER_REPO_WORKTREE, its git fetch/branch-update paths coordinate with the worker through the same cross-process repo lock.
WORKER_EVOLUTION_GLOBAL_GOAL defaults to a generic improvement objective, but
you will usually want to override it with a repository-specific goal.
Lease recovery is enabled by default. Tune it with:
SCHEDULER_STALE_RUNNING_RECLAIM_BATCH_SIZESCHEDULER_STALE_RUNNING_MAX_RECOVERY_ATTEMPTS
If MAPELITES_CODE_EMBEDDING_MODEL is not a local-hash variant, preflight also requires
either OPENAI_API_KEY / LORELEY_LLM_API_KEY, or dynamic auth via
OPENAI_DYNAMIC_API_KEY_PROVIDER plus OPENAI_DYNAMIC_API_KEY_TTL_SECONDS.
On first start the scheduler performs a repo-state root scan at MAPELITES_EXPERIMENT_ROOT_COMMIT
and requires operator approval. In non-interactive environments, pass --yes or set
SCHEDULER_STARTUP_APPROVE=true.
If you are upgrading an older schema-version-5 database, migrate it before startup:
uv run loreley db migrate
With DB_AUTO_MIGRATE=true (the default), scheduler startup initializes empty
databases and runs the same migration under a Postgres advisory lock before
marker validation. With DB_AUTO_MIGRATE=false, scheduler preflight and startup
require uv run loreley db migrate to have completed first.
For schema inspection and validation, see Database schema commands.
Options¶
--once: execute a single scheduling tick and exit.--yes: auto-approve startup approval and start without prompting.--no-preflight: skip preflight validation.--preflight-timeout-seconds: network timeout used for DB/Redis connectivity checks.--log-level: global option (pass before the subcommand) that overridesLOG_LEVELfor this invocation.
Logs¶
Logs are written to:
logs/{experiment_namespace}/scheduler/scheduler-YYYYMMDD-HHMMSS.log
Each tick log also includes reclaimed_pending and reclaimed_failed, which show how many stale or malformed RUNNING jobs were requeued or failed during that tick.
Dispatch also includes stale QUEUED rows older than WORKER_JOB_LEASE_TTL_SECONDS. This repairs broker-loss or scheduler-restart cases where a row was persisted as queued but no worker started it.
For lease recovery triage and manual retry steps, see Job lease recovery.
Exit codes¶
0: success1: startup or preflight failure2: refused to start (e.g. lock contention)