diff --git a/README.md b/README.md index 3b01831..267c16c 100644 --- a/README.md +++ b/README.md @@ -157,7 +157,7 @@ Sequenced bridge: convert the computational finding + your credential network (G

✅ Roadmap Execution

-**14/25 done (56%).** Each execution is a checkbox with a before→after eval; a box only ticks with a real result (`done` requires a non-pending before AND after — no evidence ⇒ not done, gated in CI). +**15/26 done (58%).** Each execution is a checkbox with a before→after eval; a box only ticks with a real result (`done` requires a non-pending before AND after — no evidence ⇒ not done, gated in CI). - [x] **E1** (P1 · Foundation) — Stand up the AI-native loop (repo + self-audit + gated `make check`) - [x] **E2** (P1 · Foundation) — Map the field into a verified knowledge base @@ -184,6 +184,7 @@ Sequenced bridge: convert the computational finding + your credential network (G - [x] **E23** (P1 · Foundation) — Hub architecture (knowledge·tooling·experts per cited repo) + the per-repo generation-recipe layer - [x] **E24** (P1 · Foundation) — Hub Phase-2: JIT deep artifacts for one repo (pyaging) — knowledge graph + gated skill, SHA-stamped - [x] **E25** (P1 · Foundation) — Make /longevity-loop an invocable skill that uses every hub toolset (backbone + progressive disclosure) +- [x] **E26** (P1 · Foundation) — Fan the hub out to Biolearn (North-Star toolset) — auto-wires into /longevity-loop ### Eval reports — before → after @@ -214,6 +215,7 @@ Sequenced bridge: convert the computational finding + your credential network (G | ✅ E23 | a fresh, cheap, future-proof way to offer a KG + agentic tooling for each cited repo | cited repos listed in stack.yml but no KG/tooling per repo; no design for how to do it well | docs/HUB_ARCHITECTURE.md (index+JIT design; reuse graphify/understand/reverse; MCP; SHA-cached) + scripts/repos.py → docs/REPOS.md (22 repos, per-repo KG + reverse recipes), gated in make check | | ✅ E24 | a real, grounded, provenance-stamped KG + skill generated from a cited repo, with a freshness gate | hub had the recipe layer only; no deep artifact proving the JIT layer works | hub/pyaging/ — knowledge-graph.json (20 nodes/edges) + compute-aging-clocks SKILL.md + manifest (SHA c2b3000e3c2c); scripts/hub_gen.py gates integrity (make check) + checks live staleness (FRESH); grounded in pyaging's real API | | ✅ E25 | an invocable /longevity-loop skill that reaches all per-repo toolsets without bloat | hub toolsets existed (hub/*/SKILL.md) but nothing exposed them through one invocable skill | SKILL.md generated by scripts/skill_gen.py — backbone = the loop's own tools; progressive disclosure = hub toolsets (auto-discovered from hub/, 1 today: compute-aging-clocks) + a JIT recipe; drift-gated in make check; installed at ~/.claude/skills/longevity-loop | +| ✅ E26 | the North-Star repo has a grounded KG + gated skill, auto-disclosed by /longevity-loop | hub had 1 exemplar (pyaging); Biolearn (the leaderboard/loader for E6/E7) had no toolset | hub/biolearn/ — knowledge-graph.json (19 nodes/edges) + biolearn-leaderboard SKILL.md (real API, ties to E6/E7) + manifest (SHA 0d714f5a0c0a, FRESH); skill_gen auto-discovered it → SKILL.md now discloses 2 toolsets, no hand-editing | --- diff --git a/SKILL.md b/SKILL.md index 51f4fba..6a33ba1 100644 --- a/SKILL.md +++ b/SKILL.md @@ -22,10 +22,11 @@ The loop's discipline governs every action: **no evidence ⇒ no claim** · comp ## Progressive disclosure — per-repo toolsets (load on trigger) -**1 toolset(s)** generated from cited repos (the hub — see `docs/HUB_ARCHITECTURE.md`). Load a toolset's `SKILL.md` **only when its trigger matches** — don't carry them all. Each is grounded in its source repo at a pinned commit SHA (freshness: `make hub` / `python3 scripts/hub_gen.py --refresh`). +**2 toolset(s)** generated from cited repos (the hub — see `docs/HUB_ARCHITECTURE.md`). Load a toolset's `SKILL.md` **only when its trigger matches** — don't carry them all. Each is grounded in its source repo at a pinned commit SHA (freshness: `make hub` / `python3 scripts/hub_gen.py --refresh`). | Toolset | Load when (trigger) | Read | Source @ SHA | |---|---|---|---| +| `biolearn-leaderboard` | Load the Biomarkers-of-Aging Challenge data, compute a panel of aging clocks, and build a leaderboard submission with Biolearn. Trigger for running Turn 01 on real data (E6), the first leaderboard submission (E7), or any standardized aging-biomarker load/score task. | `hub/biolearn/SKILL.md` | bio-learn/biolearn @ `0d714f5a0c0a` | | `compute-aging-clocks` | Compute a panel of biological-age (epigenetic) clocks from methylation/omics data with pyaging, then hand the panel to clockbench to quantify cross-clock disagreement. Trigger when you need biological-age estimates, a clock panel, or the disagreement signal for the Biomarkers-of-Aging / Turn-01 work. | `hub/pyaging/SKILL.md` | rsinghlab/pyaging @ `c2b3000e3c2c` | ## Reaching a toolset that doesn't exist yet (just-in-time) diff --git a/data/executions.yml b/data/executions.yml index eabb29e..4d3a3a4 100644 --- a/data/executions.yml +++ b/data/executions.yml @@ -186,3 +186,12 @@ before: "hub toolsets existed (hub/*/SKILL.md) but nothing exposed them through one invocable skill" after: "SKILL.md generated by scripts/skill_gen.py — backbone = the loop's own tools; progressive disclosure = hub toolsets (auto-discovered from hub/, 1 today: compute-aging-clocks) + a JIT recipe; drift-gated in make check; installed at ~/.claude/skills/longevity-loop" proof: "SKILL.md · scripts/skill_gen.py · make check" +- id: E26 + phase: "P1 · Foundation" + item: "Fan the hub out to Biolearn (North-Star toolset) — auto-wires into /longevity-loop" + done: true + eval: + metric: "the North-Star repo has a grounded KG + gated skill, auto-disclosed by /longevity-loop" + before: "hub had 1 exemplar (pyaging); Biolearn (the leaderboard/loader for E6/E7) had no toolset" + after: "hub/biolearn/ — knowledge-graph.json (19 nodes/edges) + biolearn-leaderboard SKILL.md (real API, ties to E6/E7) + manifest (SHA 0d714f5a0c0a, FRESH); skill_gen auto-discovered it → SKILL.md now discloses 2 toolsets, no hand-editing" + proof: "hub/biolearn/* · SKILL.md (2 toolsets) · make check" diff --git a/hub/biolearn/SKILL.md b/hub/biolearn/SKILL.md new file mode 100644 index 0000000..62dae59 --- /dev/null +++ b/hub/biolearn/SKILL.md @@ -0,0 +1,59 @@ +--- +name: biolearn-leaderboard +description: Load the Biomarkers-of-Aging Challenge data, compute a panel of aging clocks, and build a leaderboard submission with Biolearn. Trigger for running Turn 01 on real data (E6), the first leaderboard submission (E7), or any standardized aging-biomarker load/score task. +source: bio-learn/biolearn @ 0d714f5a0c0a +generated_by: longevity-loop hub (scripts/hub_gen.py) — grounded in bio-learn.github.io docs, not invented +--- + +# biolearn-leaderboard (via Biolearn) + +Generated by the longevity-loop **hub** (docs/HUB_ARCHITECTURE.md) as a Phase-2 deep toolset. +Biolearn is the **North Star** — the standardized platform the Biomarkers-of-Aging Challenge +leaderboard runs on — so this toolset is the direct path to the loop's low-hanging fruit +(**E6** run Turn 01, **E7** first submission). Grounded at the pinned `source` SHA; regenerate +when it changes (`scripts/hub_gen.py --refresh`). + +## When to use +You need to load the challenge (or GEO/NHANES/Framingham) data in a standardized form, compute +aging clocks, or assemble a leaderboard submission — i.e. to run Turn 01 for real or to submit. + +## Install +```bash +pip install biolearn +``` + +## The documented workflow (Biolearn's real API) +```python +from biolearn.data_library import DataLibrary +from biolearn.model_gallery import ModelGallery + +# 1. Load a dataset (standardized) -> GeoData with .dnam (methylation) and .metadata (age, outcomes). +data = DataLibrary().get("").load() # exact id: see the "Exploring the Challenge Data" example +# data.dnam # methylation matrix (samples x CpGs) +# data.metadata # age, sex, outcomes, ... + +# 2. Compute a clock (or a panel) from the Model Gallery. +gallery = ModelGallery() +result = gallery.get("Horvathv1").predict(data) # also PhenoAge, GrimAge, DunedinPACE, ... +# result holds the predicted biological age per sample. +``` + +## Two examples that ARE E6 and E7 (use them directly) +Biolearn ships these — start from them rather than writing from scratch: +- **"Exploring the Challenge Data"** (`auto_examples/02_challenge_submissions/`) → the exact loader + for Turn 01 / E6. +- **"Building a competition submission using an existing model"** → the E7 submission path. + +## Hand off to the loop (why this toolset exists) +Compute a **panel** of clocks, export the per-clock predicted ages to a CSV (rows = samples, +header = clock names), then measure cross-clock disagreement — the measurable core of G1: +```bash +python3 scripts/clockbench.py --input clocks.csv +``` +That is the full E6 chain: Biolearn (load + score the panel) → clockbench (disagreement) → +fill `turns/turn-01-biolearn-baseline/PROOF.md` → submit (E7). + +## Discipline +Predicted ages / ranks are **computational results on public data** — label them as such, report +the null if CIs overlap, and keep them separate from any wet-lab claim. Verify exact dataset IDs +and clock names against the current Biolearn examples (they evolve); `no evidence ⇒ no claim`. diff --git a/hub/biolearn/knowledge-graph.json b/hub/biolearn/knowledge-graph.json new file mode 100644 index 0000000..bd30205 --- /dev/null +++ b/hub/biolearn/knowledge-graph.json @@ -0,0 +1,52 @@ +{ + "schema": "longevity-loop hub knowledge graph — portable nodes/edges JSON", + "source": { + "repo": "bio-learn/biolearn", + "url": "https://github.com/bio-learn/biolearn", + "sha": "0d714f5a0c0a", + "grounded_in": "bio-learn.github.io quickstart + auto_examples index (documented API + real example titles)" + }, + "nodes": [ + {"id": "repo:biolearn", "label": "biolearn", "type": "repo", "note": "standardized aging-biomarker platform; powers the Biomarkers-of-Aging Challenge"}, + {"id": "mod:data_library", "label": "biolearn.data_library", "type": "module"}, + {"id": "mod:model_gallery", "label": "biolearn.model_gallery", "type": "module"}, + {"id": "cls:DataLibrary", "label": "DataLibrary", "type": "class", "note": ".get(id).load() -> GeoData"}, + {"id": "cls:GeoData", "label": "GeoData", "type": "class", "note": "attributes: .dnam (methylation matrix), .metadata (age, outcomes)"}, + {"id": "cls:ModelGallery", "label": "ModelGallery", "type": "class", "note": ".get(clock).predict(dnam)"}, + {"id": "fn:load", "label": "DataLibrary.get().load()", "type": "function"}, + {"id": "fn:predict", "label": "ModelGallery.get().predict()", "type": "function"}, + {"id": "concept:clock", "label": "aging clock", "type": "concept"}, + {"id": "clock:Horvath", "label": "Horvath", "type": "clock"}, + {"id": "clock:DunedinPACE", "label": "DunedinPACE", "type": "clock"}, + {"id": "data:geo", "label": "GEO", "type": "data-source"}, + {"id": "data:nhanes", "label": "NHANES", "type": "data-source"}, + {"id": "data:framingham", "label": "Framingham", "type": "data-source"}, + {"id": "ex:challenge", "label": "example: Exploring the Challenge Data", "type": "example", "note": "auto_examples/02_challenge_submissions/"}, + {"id": "ex:submission", "label": "example: Building a competition submission", "type": "example"}, + {"id": "ext:leaderboard", "label": "Biomarkers of Aging Challenge (leaderboard)", "type": "downstream"}, + {"id": "ext:turn01", "label": "longevity-loop Turn 01 (E6)", "type": "downstream"}, + {"id": "ext:clockbench", "label": "longevity-loop clockbench (G1)", "type": "downstream"} + ], + "edges": [ + {"source": "repo:biolearn", "target": "mod:data_library", "rel": "contains"}, + {"source": "repo:biolearn", "target": "mod:model_gallery", "rel": "contains"}, + {"source": "mod:data_library", "target": "cls:DataLibrary", "rel": "defines"}, + {"source": "mod:data_library", "target": "cls:GeoData", "rel": "defines"}, + {"source": "mod:model_gallery", "target": "cls:ModelGallery", "rel": "defines"}, + {"source": "cls:DataLibrary", "target": "fn:load", "rel": "has"}, + {"source": "fn:load", "target": "cls:GeoData", "rel": "produces"}, + {"source": "cls:ModelGallery", "target": "fn:predict", "rel": "has"}, + {"source": "fn:predict", "target": "concept:clock", "rel": "runs"}, + {"source": "clock:Horvath", "target": "concept:clock", "rel": "is-a"}, + {"source": "clock:DunedinPACE", "target": "concept:clock", "rel": "is-a"}, + {"source": "cls:DataLibrary", "target": "data:geo", "rel": "loads-from"}, + {"source": "cls:DataLibrary", "target": "data:nhanes", "rel": "loads-from"}, + {"source": "cls:DataLibrary", "target": "data:framingham", "rel": "loads-from"}, + {"source": "ex:challenge", "target": "ext:turn01", "rel": "enables"}, + {"source": "ex:submission", "target": "ext:leaderboard", "rel": "enables"}, + {"source": "repo:biolearn", "target": "ext:leaderboard", "rel": "powers"}, + {"source": "fn:predict", "target": "ext:clockbench", "rel": "feeds"}, + {"source": "cls:GeoData", "target": "ext:turn01", "rel": "consumed-by"} + ], + "counts": {"nodes": 19, "edges": 19} +} diff --git a/hub/biolearn/manifest.json b/hub/biolearn/manifest.json new file mode 100644 index 0000000..0727170 --- /dev/null +++ b/hub/biolearn/manifest.json @@ -0,0 +1,15 @@ +{ + "repo": "bio-learn/biolearn", + "url": "https://github.com/bio-learn/biolearn", + "source_sha": "0d714f5a0c0a", + "generated_at": "2026-07-19", + "license_note": "not verified this run — confirm at the repo before redistribution", + "one_line": "Open, standardized platform for aging biomarkers — dataset loaders + a model gallery of clocks; the Biomarkers-of-Aging Challenge leaderboard runs on it.", + "artifacts": ["knowledge-graph.json", "SKILL.md"], + "engines": { + "knowledge_graph": "grounded from bio-learn.github.io quickstart + example index (production: graphify / understand-anything)", + "skill": "grounded from Biolearn's documented API + example titles (production: anyagent reverse -> refine)" + }, + "provenance_note": "Grounded in bio-learn.github.io docs + example titles at source_sha; exact dataset IDs / args are deferred to the cited example files rather than invented (no evidence => no claim). Regenerate when source_sha changes (scripts/hub_gen.py --refresh).", + "why": "Biolearn IS the North Star — the leaderboard + the challenge-data/clock loader that E6 (run Turn 01) and E7 (first leaderboard submission) directly depend on. Highest-value toolset in the hub." +}