Submit to the Hub¶
The galapagos Hub is a registry for scaffold cards, task cards, and discoveries, with a leaderboard that exposes each row's review status. Everything bundled in the library mirrors to the Hub (library ⊆ hub). You contribute three kinds of artifact: a scaffold card, a task card, or a discovery (a claimed result for review).
1. Lay out the repo¶
A submission is a repo, HuggingFace-Hub-style: the folder that holds card.yaml. submit
uploads card.yaml plus every file the card references — component file paths and any assets —
so the Hub can serve the repo's files, not just a metadata stub. All referenced paths must live under
the card's directory (no .. escapes or absolute paths).
my_task/
├── card.yaml # the manifest (points at the files below)
├── initial_program.py # components.initial_program (the seed)
├── evaluator.py # components.evaluator
├── Dockerfile # the task's environment — bundled automatically, and required
├── README.md # bundled automatically if present
└── data/small/ # assets: [ "data/small/**" ]
Big datasets are not uploaded. Declare them under external_resources (a uri + sha256); the
bytes stay on their own host (HF Datasets / S3 / GCS) and load_task() fetches them at load time.
See Cards → Assets and external resources.
For scaffold repos, include any default config.yaml in assets if you want it uploaded; the current
bundle collector does not include a sibling config file automatically unless the card references it as
an asset or component file.
2. Preview the bundle¶
--dry-run validates the card against its pydantic schema and lists exactly
what would be uploaded, without touching the network:
galapagos submit --repo-type task --card-path my_task/card.yaml --dry-run
# valid task card: my_task (our_org/my_task)
# bundle → 5 files, 0.6 KiB
# card.yaml 554 B
# evaluator.py 52 B
# initial_program.py 44 B
# data/small/a.txt 3 B
# README.md 10 B
# external_resources (declared; fetched at load, not uploaded): benchmark_data
The kind is auto-detected (a card with metric(s)/domain is a task) or set with --repo-type. An
invalid card prints the error and exits non-zero.
3. Get a Hub token¶
Uploads require an Authorization: Bearer <token> header. Mint one from a running instance (in dev,
issuance is open; in prod the request must carry a Bearer credential — a Supabase login token, or the
hub admin token) and export it so the CLI picks it up:
# in prod, also pass the credential: -H "authorization: Bearer <supabase-login-or-admin-token>"
export GALAPAGOS_HUB_TOKEN=$(curl -sX POST https://open-galapagos.com/api/auth/token \
-H 'content-type: application/json' -d '{"label":"me"}' \
| python -c 'import sys,json; print(json.load(sys.stdin)["token"])')
4. Upload the repo¶
# task — uploads card.yaml + referenced files, and the repo appears on the website
galapagos submit --repo-type task --card-path my_task/card.yaml
# uploaded task our_org/my_task → https://open-galapagos.com/tasks/my_task
# scaffold — same command, kind auto-detected
galapagos submit --repo-type scaffold --card-path my_scaffold/card.yaml
Point at a self-hosted Hub with --hub-url (or $GALAPAGOS_HUB_URL). Under the hood the CLI POSTs a
multipart bundle to /api/{kind}/upload; the Hub re-validates the card, stores the files, and
catalogs a community row. It never imports your controller/evaluator — cards + files are inert
data on the Hub.
| Endpoint | Body | Purpose |
|---|---|---|
POST /api/tasks/upload |
multipart bundle (card.yaml + files) |
upload a task repo (what galapagos submit uses) |
POST /api/scaffolds/upload |
multipart bundle (card.yaml + files) |
upload a scaffold repo |
POST /api/tasks / POST /api/scaffolds |
{"card_yaml": "..."} |
register a card only (no files — metadata stub) |
POST /api/discoveries/upload |
multipart bundle (card.yaml + solution/trajectory) |
upload a discovery repo (lands pending) |
POST /api/discoveries |
{"card_yaml": "..."} |
register a discovery card only |
POST /api/discoveries/{name}/review |
{"status": "accepted"} |
review a discovery (pending → accepted | rejected) |
GET /api/tasks/{name}/tree · /raw?path= |
— | list + download a repo's files (open, no token) |
GET /api/scaffolds / GET /api/tasks |
— | browse the catalog (open, no token) |
Library cards (the bundled ones) cannot be overwritten — a community upload with a clashing name is
rejected with 409. A scaffold card with a controller (a dotted Scaffold-subclass path) is
catalogued as a runnable method; a status: spec card is published as a design entry. The browser
Playground runs only bundled code: the live demo runs a fixed allowlist of bundled scaffolds
(openevolve, topk, best_of_n, best_of_n_attempts) on the bundled circle_packing task, and
the Discovery Space uses the scaffold/provider allowlist returned by /api/discovery/options and
runnable compatible bundled tasks. claude_code and meta_harness are local-only because their
defaults use Claude subscription authentication; neither hosted runner imports or runs submitted
controllers.
See Write your own scaffold and
Write your own task for how to build the cards, and
Submit a scaffold for a worked end-to-end repository submission.
Loading a submitted task¶
Once uploaded, anyone pulls the repo with GalapagosTask.from_card — it downloads the bundle into
the local cache ($GALAPAGOS_CACHE_DIR, default ~/.cache/galapagos) and returns a task whose files
are materialized on disk. Opt into separately hosted external_resources when the task declares
them:
import galapagos as gx
task = gx.GalapagosTask.from_card(
"our_org/my_task", download_external=True
) # bundled/local -> cache -> Hub
task.root # the materialized repo dir
task.initial_program_source # the seed program's text
task.evaluator # the deterministic scorer
gx.GalapagosTask.from_card("our_org/my_task", local_path="./my_task")
gx.GalapagosTask.from_card("our_org/my_task", source="hub") # always re-fetch
The default source="auto" reaches the network only once: a repo already in the cache is reused as
is. source="local" restricts resolution to cards bundled in the wheel and raises for a Hub repo
like our_org/my_task; source="hub" forces a fresh download over the cached copy. gx.load_task()
remains a compatibility wrapper and fetches external_resources by default.
Hub scaffold repos are browsable and downloadable through the Hub file endpoints, but
gx.load_scaffold("org/name") does not yet download scaffold repos into the cache. Today, load a
submitted scaffold by installing/importing its controller package or by materializing the repo yourself
and passing path=".../card.yaml".
5. Submit a discovery¶
The interesting submission is a discovery: you ran a scaffold (or an agent) on a task and found a
solution worth a place on the leaderboard. That goes through the discovery repo — a bundle of
card.yaml + the best solution + the run trajectory, uploaded with POST /api/discoveries/upload
(or registered card-only via POST /api/discoveries with {"card_yaml": ...}). It lands pending;
a reviewer flips it with POST /api/discoveries/{name}/review
(pending → accepted | rejected) — accepting creates or updates the leaderboard entry from the
submitted claim. The endpoint does not itself replay the trajectory or re-score the solution.
There is currently no discovery mode in galapagos submit; use the API directly or the browser
Discovery Space, whose completed runs are published by the backend.
For a current ETIF run, the trajectory portion contains one
trajectory/evolutionary_trajectory.jsonl stream. It contains candidate creation alongside
evaluator failures, migration, crossover, adaptation, model/agent/tool activity, checkpoints, and
final evaluation. Tool-enabled local runs additionally keep their tool-only ledger and cumulative
checkpoint snapshots as operational artifacts.
A lightweight claim can also be filed as a VerificationCard via POST /api/verifications; it
is always stored unverified and browsable via GET /api/verifications, with no review transition
or leaderboard linkage. Validate it locally first, then POST it as a JSON object:
# my_discovery.yaml — the VerificationCard
task: circle_packing
scaffold: openevolve # the scaffold OR `agent:` that produced it
submitter: you@example.com
claimed_score: 2.634
best_solution: best_program.py # inline code, or a path/URI
trajectory: runs/openevolve/circle_packing/2026-06-08/ # the full discovery trajectory
notes: "100 iterations, gpt-5.5 via OpenRouter; reproduces best_known."
# the verifications endpoint takes the card as a JSON object (not raw YAML)
curl -X POST https://open-galapagos.com/api/verifications \
-H "authorization: Bearer $TOKEN" -H "content-type: application/json" \
-d "$(python -c 'import json,yaml; print(json.dumps(yaml.safe_load(open("my_discovery.yaml"))))')"
| Field | Meaning |
|---|---|
task |
the task the discovery is on |
scaffold / agent |
what produced it (one of the two) |
claimed_score |
the score you are claiming |
best_solution |
the discovered artifact (inline or a path) |
trajectory |
path/URI to the full discovery trajectory (for reproducibility) |
notes |
free-form reproduction notes |
The submitter never sets their own initial review state: a verification always lands unverified
regardless of what the card says, and a discovery repo lands pending. A reviewer may promote it to
accepted or mark it rejected. Every entry appears with its review status. The current backend
records that decision but does not enforce who performed the review or which reproduction checks
were run, so review policy must be applied operationally.
The leaderboard¶
The Hub ranks entries by their submitted score, highest first (ties broken by recency). Scores are
self-reported at submission time. An accepted badge records a review decision; it does not prove
that the backend automatically reproduced the score. Compare entries within a single task and apply
the deployment's review policy when interpreting them. Browse it filtered by task or scaffold:
A leaderboard entry is submitted (with a token) via POST /api/leaderboard and lands pending; a
reviewer flips it with POST /api/leaderboard/{id}/verify (pending → accepted | rejected); the
board lists every entry with its status badge.
See The Hub for running a Hub instance locally and the full endpoint summary.