| name | meda |
| description | Biology-informed symbolic regression for ODE discovery. The Literature agent produces a broad domain dump; the Formalizer curates it into a problem-specific set of constraints and seeds; a genetic algorithm searches for sparse ODEs that satisfy those constraints. Optionally anchored to time-series data when provided. Trigger on: "symbolic regression", "ODE discovery", "find the equation for", "knowledge-informed modeling", or any biological system where the user wants a mathematical model — with or without empirical data.
|
MEDA — Orchestrator
You orchestrate MEDA.
It finds sparse ODE systems that satisfy literature-derived biological
constraints, optionally anchored to time-series data.
The pipeline runs in one of two modes:
constraint_only (default) — no data needed. Explorer is
skipped. Fitness combines constraint satisfaction with a sparsity
reward (penalty on the number of terms used). Report validates the
discovered system by forward-simulating it and checking against
dynamical signatures from the literature.
data_anchored — user supplies DATA_FILE. All sub-agents run.
Fitness combines constraint satisfaction, data fit, and the sparsity
reward.
You run Steps 0 and 5.5 yourself. Steps 1–5 and Step 6 are each a
sub-agent: a separate Claude session that reads its own
agents/<name>.md and writes a defined set of artifacts. You invoke
each sub-agent, check its outputs, and move on.
Agent roles (high-level)
- Literature — broad, well-cited domain dump. Three sections:
Constraints (every property the literature implies), Models (every
canonical ODE model that could fit), Other (plot conventions,
dynamical signatures, etc.). Does not curate or pick one model.
- Formalizer — the curator. Selects which constraints apply (with
reject reasons), translates the literature's vocabulary into the
user's variables, picks one or more models as seeds, assigns weights
via one of three strategies (
equi_weighted default, tiered,
per_constraint), and writes problem.json.
- Runner — invokes the GA. Tests all seeds the Formalizer chose.
- Report / Recapper — diagnostics and final summary.
- Evaluator — runs only when ground truth is supplied. Quantifies the
discovered system against the true ODEs across five metric families
(variable, constraint, term, equation recovery, biological plausibility)
and writes
metrics.md.
What the user gives you
- Variable info — names, descriptions, and (if applicable) which
column is time. Required.
DATA_FILE — path to a time-series CSV. Optional. If absent,
mode is constraint_only.
- Setup overrides (optional) — fields to override in
setup.default.yaml, including weighting_strategy.
- Ground-truth equations (optional) — when the user knows the true
ODE system (synthetic benchmark, textbook system, prior fit), they
may supply it in LaTeX, plain math, or prose. The user can provide
it either up front (Step 0) or after seeing the Report (Step 5.5);
the orchestrator records it in a separate file,
ground_truth.md,
that only the Recapper and Evaluator are instructed to read. The
Literature, Formalizer, Runner, and Report agents are never told this
file exists. Not used during the search itself — the GA never sees the
ground truth. Only the Recapper and Evaluator do, and both run after the
search completes.
If variable info is missing, ask for it before doing anything else.
Standing rules
- One session, one directory. Everything for a run lives under
SESSION_DIR = sessions/session_<N>/. All paths below are relative
to SESSION_DIR/.
context.md holds the problem statement and the mode. Step 0
writes it.
- Verify outputs before moving on. After a sub-agent returns,
check that the artifacts listed in its step section exist and are
non-empty.
- On failure: re-read the agent's
.md, re-invoke once, then stop
and report if it fails again. Do not silently continue past a
missing or empty artifact.
- Sub-agents read their own
.md. You hand them the file and a
short context message. You do not summarize or rewrite their
instructions.
Step 0 — Setup (you)
In: variable info, optional DATA_FILE, optional setup overrides.
Out: setup.yaml, context.md.
1. Resolve mode. If DATA_FILE is supplied, mode = data_anchored.
Otherwise mode = constraint_only.
2. Create the session directory.
Before deciding N, run this shell command to check what sessions
actually exist on disk right now:
find sessions/ -maxdepth 1 -type d -name 'session_[0-9]*' 2>/dev/null | grep -oE '[0-9]+$' | sort -n | tail -1
If the command produces a number, N = that number + 1. If it produces
nothing, N = 1. Do not infer N from memory or prior conversation;
always run the command and read its output.
mkdir -p sessions/session_<N>/logs
3. Write setup.yaml. Copy skills/meda/setup.default.yaml
into SESSION_DIR/setup.yaml. Set the top-level mode field. Apply
user overrides — including weighting_strategy (equi_weighted /
tiered / per_constraint) if the user specified one.
4. Write context.md. Create a problem section with variable
names, variable descriptions, mode, and — if data_anchored —
data_file and time_column. Include any other problem-level fields
the user supplied. Do not include ground-truth equations here.
5. (Optional) Write ground_truth.md. Only if the user supplied
ground-truth equations. Write the equations exactly as the user
provided them (LaTeX, plain math, or prose) — do not rewrite,
simplify, or normalize. This file is read only by the Recapper and the
Evaluator. The context messages you send to the Literature, Formalizer,
Runner, and Report agents must not mention ground_truth.md or its
contents; if they don't know it exists, they can't peek. Only the
Recapper's and Evaluator's launch messages name the file.
Step 1 — Explorer (skipped if mode = constraint_only)
Agent file: agents/explorer.md
In: SESSION_DIR, DATA_FILE.
Out: eda/data_exploration.md, eda/explore_output.json. Optional:
eda/sindy_screen.json, eda/extensions_output.json,
eda/extensions.py. Log in logs/explore_baseline.log.
Step 2 — Literature
Agent file: agents/literature.md
In: SESSION_DIR.
Out: lit_review.md with three sections: Constraints, Models,
Other relevant information.
Step 3 — Formalizer
Agent file: agents/formalizer.md
In: SESSION_DIR.
Out: problem.json (with ode_variables, weighting_strategy,
constraints, multi-element seeds), constraints.md.
Step 3.5 — Validate problem.json (you)
In: SESSION_DIR/problem.json, SESSION_DIR/setup.yaml.
Out: nothing (gate only).
Run the validator before invoking the Runner:
cd SESSION_DIR && uv run python ../../.claude/skills/meda/scripts/validation.py \
--setup ./setup.yaml \
--problem ./problem.json
If the command exits 0, proceed to Step 4.
If it exits non-zero, read the error from stderr. The validator catches
two classes of bugs that silently corrupt GA results:
-
Wrong field names — "with_variable", "reference", or "value"
on a rate/special/ratio constraint instead of "target". The
loader reads target exclusively; these aliases resolve to the default
of 0 and produce always-wrong constraint scores.
-
Hard constraint contradictions — a hard term constraint requiring
the linear self-term of variable V to be positive, paired with a hard
rate constraint requiring d(V)/dt < 0 when V > 0 and all others = 0
(or the symmetric negative/gt pair). These cannot both be satisfied by
any polynomial ODE; all seeds and all evolved candidates will have
hard_pass = False from generation 0.
On failure: paste the full validator error into the Formalizer re-invocation
message and request a targeted fix. Do not silently continue past a
failed validator — the GA will produce a degenerate result and waste the
full compute budget.
Step 4 — Runner
Agent file: agents/runner.md
In: SESSION_DIR, DATA_FILE (only if data_anchored).
Out: search/results.json, search/checkpoint.json,
symbolic_regression.md. Log in logs/runner.log.
Step 5 — Report
Agent file: agents/report.md
In: SESSION_DIR.
Out: report/summary.md, report/diagnostics.json,
report/figures/ (with figure_index.md). Log in
logs/report_baseline.log.
Step 5.5 — Ground-truth check-in (you)
In: SESSION_DIR.
Out: ground_truth.md (only if newly supplied here).
This step gives the user a chance to provide ground truth after
seeing the Report — useful for running the search blind first and
checking against truth afterwards.
Skip this step if ground_truth.md already exists from Step 0 (the
user gave it up front). Otherwise:
-
Ask the user, in one short message: do they want to supply
ground-truth equations before the Recapper runs? Show them the
Report's Status line so they have context. Keep the ask
neutral — don't push for an answer either way.
-
If the user provides equations, write them verbatim to
ground_truth.md (LaTeX, plain math, or prose — whatever they
gave). Same rules as Step 0 part 5: do not rewrite, simplify, or
normalize. The Literature, Formalizer, Runner, and Report agents
have already completed and never see this file.
-
If the user declines or doesn't respond with equations, proceed
without ground_truth.md. The Recapper will skip its
ground-truth-comparison section.
Do not run this step more than once per session.
Step 6 — Recapper
Agent file: agents/recapper.md
In: SESSION_DIR. Also ground_truth.md, if present (from Step 0
or Step 5.5).
Out: recap.md.
Writes a short postmortem with system-level recommendations. If
ground_truth.md exists, the Recapper reads it and produces a
structural and coefficient comparison against the true equations,
using the gap to refine its systemic recommendations.
Step 7 — Evaluator (skipped if ground_truth.md is absent)
Agent file: agents/evaluator.md
In: SESSION_DIR, including ground_truth.md (from Step 0 or 5.5).
Out: metrics.md, eval_inputs.json, metrics.json. Log in
logs/evaluation.log.
Runs only when ground_truth.md exists. Quantifies the discovered system
against the true ODEs across five metric families — variable recovery,
constraint performance, term-level recovery, equation recovery (tree-edit
distance and inclusion), and biological plausibility. The Evaluator
extracts the reference structure and makes the expert judgments, then runs
scripts/evaluation_metrics.py (which reads predicted terms directly from
search/results.json) to compute the numbers, and writes metrics.md.
The Recapper's Section 4 is the prose comparison; this is the quantitative
one.
If ground_truth.md does not exist, skip this step — there is nothing to
evaluate against.
Final session layout
SESSION_DIR/ (= sessions/session_<N>/)
setup.yaml ← Step 0
context.md ← Step 0
ground_truth.md ← Step 0 or 5.5 (optional; read only by Recapper + Evaluator)
eda/ ← Step 1 (data_anchored only)
data_exploration.md
explore_output.json
extensions_output.json (if extensions ran)
extensions.py (if extensions ran)
lit_review.md ← Step 2
problem.json ← Step 3
constraints.md ← Step 3
search/ ← Step 4
results.json
checkpoint.json
symbolic_regression.md ← Step 4
report/ ← Step 5
summary.md
diagnostics.json
extensions.py (if extensions ran)
figures/
figure_index.md
*.png, *.pdf
recap.md ← Step 6
eval_inputs.json ← Step 7 (only if ground_truth.md exists)
metrics.json ← Step 7 (only if ground_truth.md exists)
metrics.md ← Step 7 (only if ground_truth.md exists)
logs/
explore_baseline.log (data_anchored only)
extensions.log (if extensions ran)
runner.log
report_baseline.log
evaluation.log (only if ground_truth.md exists)