The research workspace¶
A Science ADK project is a directory of plain files under version control.
There is no database, no server and no hidden state: the files in research/
are the complete empirical truth of the project.
Layout¶
my-research/
├── science.toml # project config: tools, run limits
├── GOAL.md # the question, the metric, the threshold
├── .gitignore
├── tools/ # local tools, auto-registered
│ └── example.py
├── research/
│ └── 001-my-hypothesis/ # one directory per experiment
│ ├── HYPOTHESIS.md # the claim, its rationale, its lineage
│ ├── workflow.json # the typed DAG
│ ├── agents/
│ │ ├── config.py
│ │ ├── fetch.py
│ │ └── evaluate.py
│ └── runs/
│ └── 20260820-053012/ # one directory per execution
│ ├── trace.json # the complete record
│ ├── score.json # gates, pillars, rationale
│ ├── REPORT.md # written from the trace
│ └── data/ # artifacts and figures
├── LEARNINGS.md # append-only empirical memory
└── CAMPAIGN.md # the leaderboard across experiments
science.toml marks the project root. Every command searches upward from the
current directory to find it, so you can run science-adk run from anywhere
inside the tree; --path DIR overrides the search.
GOAL.md¶
One question, one metric, one threshold. The frontmatter is what the framework reads:
---
question: Does Kepler's Third Law hold for exoplanets discovered by modern surveys?
target_metric: r_squared
target_value: 0.95
---
# Research Goal
## Question
## Background
## Success
## Constraints
Set it from the CLI or edit it by hand:
science-adk goal --set-question "..." --metric r_squared --target 0.95
science-adk goal # show the current goal
The threshold lives here on purpose
target_value is compared against the run's observed value outside the
workflow. No node ever sees it. An evaluation agent that could read the
number it must beat is one that will eventually be written to beat it.
Experiments¶
science-adk experiment new "Orbital period scales as the 3/2 power of semi-major axis" \
--rationale "..." --parent 001-earlier-experiment
The directory is named NNN-<slug of the hypothesis>, so git log and ls
both read as a history of ideas rather than a history of files. HYPOTHESIS.md
carries the claim, the rationale, the generation number, a status, and the
parent that motivated it.
---
hypothesis: Orbital period scales as the 3/2 power of semi-major axis across confirmed exoplanets
generation: 0
status: draft
created_at: 2026-08-20T00:00:00+00:00
---
# 001-kepler-exoplanets
## Hypothesis
## Rationale
Runs¶
Every execution gets its own timestamped directory — YYYYMMDD-HHMMSS in UTC,
suffixed -2, -3 … if two runs start in the same second. Runs are never
overwritten, so a project accumulates an honest history including the failures.
trace.json holds, for the whole run and for each node:
| Field | Meaning |
|---|---|
run_id, experiment, state |
Which run, of what, and how it ended. |
started_at, finished_at, duration_s |
Wall-clock timing. |
nodes[].outputs |
Every output port value, or a dataset reference. |
nodes[].logs |
Everything the agent passed to await self.log(...). |
nodes[].provenance |
Tool calls, inputs read, URLs fetched, files written. |
nodes[].fingerprint |
Hash of code + inputs + params, used by --reuse. |
nodes[].error, nodes[].traceback |
Present when a node failed. |
score.json holds the six gates with their pass/fail detail, plus the pillar
ratings and rationale once an audit has been recorded.
LEARNINGS.md and CAMPAIGN.md¶
science-adk learn "GNN embeddings cut solubility RMSE by 24% vs Morgan fingerprints." --run latest
science-adk campaign
LEARNINGS.md is append-only and demands evidence: an insight cites the run
that supports it. CAMPAIGN.md is regenerated on demand and ranks every
experiment by its audited score.
science-adk status # where the project stands right now
science-adk experiment list # every experiment and its best score
Why files¶
Because a research project outlives its tooling. Everything here is readable
by cat, diffable by git, reviewable in a pull request, and reproducible by
someone who never installs the CLI at all. The provenance guarantees are
enforced at runtime, but the record they produce is text.