agentsclimarketplace

Era

Skill mehdiforoozandeh/skills/skills/era

Agent skills for Claude Code & skills.sh-compatible agents.

Install
npx -y skills add mehdiforoozandeh/skills --skill era

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Run ERA-style empirical-software search (Google ERA / Flat UCB Tree Search) to evolve whole programs toward a scalar objective. Use for software/algorithm DESIGN: an LLM writes and rewrites complete candidate programs, a sandbox scores each, and a flat PUCT bandit (FUTS) keeps a population and decides which to improve next — escaping local optima and returning a diverse portfolio of winners. Domain-agnostic. Triggers: ERA, FUTS, Flat UCB Tree Search, empirical software search, evolutionary program search, generate_fn/execute_fn.

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

8.2 KB, as published. Nobody here has run it

ERA — empirical-software search via Flat UCB Tree Search

Faithful port of Google Research's ERA (Nature 2026, repo): an AI system that helps write high-quality empirical software. An LLM proposes whole candidate programs, a sandbox scores each, and a flat PUCT bandit (FUTS) decides which existing solution to improve next — keeping a population and escaping local optima instead of greedily climbing one trajectory. The candidate is the source code; ERA evolves the algorithm/model/pipeline, not a config.

What ERA is for: optimizing a problem that already has (a) a runnable seed program, (b) a fast automated scalar score, (c) a fixed problem definition. It evolves the code within that frame — it does not invent the frame. Skip ERA for problems with no automated score, or a single known change (just make it).

The engine (scaffold/futs.py — FROZEN, vendored verbatim)

futs.py is vendored verbatim from google-research/era (implementation/futs.py, commit eb56676ce0a9b22b0c357c218de09ac61e94fc4b, Apache-2.0). It is the neutral judge — never edit it during a search (that invalidates all node scores and cross-run comparison).

Primitives:

Problem(description)         # the problem statement + interface + scoring contract
Solution(program)            # a complete, self-contained program (source text)
Node(index, parent_index, solution, score, num_visits, rank_score, puct)
search(problem, init_sol, init_score, generate_fn, execute_fn, num_iterations, c_puct=1.0)
generate_fn: (problem, parent_solution, parent_score) -> Solution
execute_fn:  (problem, solution) -> float

PUCT selection each iteration picks the node maximising rank_score + c_puct · (1/N) · √(total_visits) / (1 + num_visits), where rank_score = rank/(N−1) ∈ [0,1] is the node's score normalised by rank, the prior is uniform 1/N, and a new node's visit backpropagates up its ancestors (backpropagate_visit). "Flat" = one global pool ranked by score; the only tree structure is parent links + ancestor visit-backprop. The 1/N prior is load-bearing: a constant prior makes exploration grow unbounded and never converge.

Concurrency + logging (scaffold/futs_batched.py — labeled extension)

Upstream ships only the sequential search() with no node hook. This separate, non-upstream module adds, reusing the frozen primitives unchanged:

  • search(..., on_node=...) — identical behaviour to futs.search plus a per-node callback (for live tree.json). Parity is asserted in selftest.py.
  • batched_search(..., batch_size) — selects B parents per round via virtual visits so B candidates are executed concurrently (B independent SLURM jobs). Generation stays sequential (one LLM call each); only execution is parallel. batch_size=1 reduces to the sequential path.

The pieces you author (per problem)

Copy scaffold/ to a working dir. Only problem.py + config.yaml change.

FileRole
problem.pyget_problem() -> (Problem, initial_solution, initial_score). Start from problem_template.py. The Problem.description states the problem, the data/interface, the rules + fixed budget, and the exact scoring contract. initial_solution is a real runnable seed program (anchors the root); initial_score=None makes the driver score it once, or pass a float. No baseline? Ship a stub printing ERA_SCORE: -1e9 and cold-start.
config.yamlbackend, exec_mode, num_iterations, batch_size, c_puct, SLURM knobs, paths.
generate.py / execute.pyThe generic generator/executor (below). Rarely need edits.

Scoring contract. Every candidate program must run under the fixed budget and print exactly one line ERA_SCORE: <float> (higher = better). Crash / OOM / timeout / missing footer → executor returns -1e9 and FUTS abandons the node. Define one clear objective in the problem and don't change it mid-search (it invalidates cross-node comparison). The candidate runs in its own temp workdir; it must be self-contained (no editing the scaffold or shared files).

Generator — subscription-authed CLI, with failover

generate_fn shells out to a terminal coding-CLI in headless mode, billing your subscription (included tokens), never a metered API key. Both run with a hard timeout and stdin-piped prompt (Cursor's -p can hang otherwise).

  • Default: Claude / latest Opusclaude -p --model opus --output-format text.
  • Failover: Cursor / latest Composercursor-agent -p -m composer --output-format text. On a Claude rolling-limit hit (detected from output), switch for a cooldown, then re-probe and switch back once it recovers.
  • Check availability: python generate.py --check.

Execution — SLURM job per run (default) or interactive (off-cluster)

  • sbatch_per_run (default). Each candidate is its own short SLURM job; a batch is submitted concurrently and harvested as jobs finish. All cluster specifics are config-driven: account, gres (omit for CPU clusters), cpus, mem, time_limit, and setup_cmds (env/module lines). Nothing cluster-specific is hardcoded.
  • interactive. Runs each candidate as a local subprocess — on a held salloc allocation, or just locally for small problems / the regression example / selftest.

Running a search

# from this skill's own directory (where this SKILL.md and scaffold/ live):
cp -r scaffold <workdir> && cd <workdir>
cp examples/regression/problem.py ./problem.py   # or write your own from problem_template.py
python selftest.py            # verify the harness (no GPU/tokens/SLURM)
python generate.py --check    # verify claude / cursor-agent are logged in
python run.py --config config.yaml

Output: tree.json (every node, rewritten live → resumable/inspectable) and a printed top-k diverse portfolio — a set of strong, distinct programs, not just the single best. A portfolio winner is a hypothesis: scores come off one evaluation, so confirm a winner with a repeat run before trusting it.

Worked example

examples/regression/ — California Housing tabular regression (faithful to the repo's playground_s3e1): the candidate is a whole program (load → features → model → evaluate), scored by negative held-out RMSE. Runs locally with exec_mode: interactive (no GPU/SLURM). Expect ERA to evolve the linear baseline into feature engineering + gradient boosting.

Defaults & knobs

  • c_puct (default 1.0): lower → greedier exploit (→0 ≈ greedy hill-climb); higher → more breadth (too high → random thrash). Collapsing to one lineage → raise it; thrashing → lower it.
  • batch_size (default 4): candidates per round = concurrent jobs (serial in interactive).
  • num_iterations: total candidates generated+executed.
  • Whole-program candidates are higher-variance than config knobs — expect many -1e9 (broken imports, shape errors, NaN). Keep the seed clean and the scoring contract crisp; raise c_puct modestly so the search doesn't abandon the lineages that compile.

Anti-patterns

  • Editing futs.py (the frozen judge) or putting non-upstream logic inside it — extensions go in futs_batched.py and reuse its primitives.
  • Non-self-contained candidates (editing the scaffold or shared files).
  • A composite score with no clear main term, or changing the metric mid-search.
  • Treating it as deep MCTS — it is flat UCB (one ranked pool; only ancestor visit-backprop, no value back-prop).

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.