lazarus-bio 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dean Sherry
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,260 @@
1
+ Metadata-Version: 2.4
2
+ Name: lazarus-bio
3
+ Version: 0.1.0
4
+ Summary: Resurrect dead research code into a callable pipeline component β€” and give the revival back.
5
+ Author-email: Dean Sherry <dean.shez@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/DoctorDean/lazarus
8
+ Project-URL: Documentation, https://doctordean.github.io/lazarus/
9
+ Project-URL: Repository, https://github.com/DoctorDean/lazarus
10
+ Project-URL: Issues, https://github.com/DoctorDean/lazarus/issues
11
+ Project-URL: Try in Colab, https://colab.research.google.com/github/DoctorDean/lazarus/blob/main/notebooks/Lazarus_Democratizing_Dead_SOTA.ipynb
12
+ Keywords: bioinformatics,reproducibility,agents,dependency-pinning,research-software,docker
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
24
+ Classifier: Topic :: Software Development :: Build Tools
25
+ Requires-Python: >=3.9
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: packaging>=21
29
+ Requires-Dist: PyYAML>=6
30
+ Provides-Extra: dev
31
+ Requires-Dist: pytest>=7; extra == "dev"
32
+ Requires-Dist: build>=1; extra == "dev"
33
+ Requires-Dist: twine>=5; extra == "dev"
34
+ Provides-Extra: agent
35
+ Requires-Dist: claude-agent-sdk>=0.2; extra == "agent"
36
+ Dynamic: license-file
37
+
38
+ <p align="center">
39
+ <img src="https://raw.githubusercontent.com/DoctorDean/lazarus/main/lazarus.png" width="440" alt="Lazarus β€” resurrecting a dead repo" />
40
+ </p>
41
+
42
+ <h1 align="center">Lazarus</h1>
43
+
44
+ <p align="center"><em>Turn dead research code into a callable pipeline component β€” and give the revival back.</em></p>
45
+
46
+ <p align="center">
47
+ 🧬 <strong>Build track</strong> · Built with <strong>Claude Science</strong> hackathon · July 2026
48
+ </p>
49
+
50
+ <p align="center">
51
+ <a href="https://pypi.org/project/lazarus-bio/"><img src="https://img.shields.io/pypi/v/lazarus-bio?color=0c8f6e" alt="PyPI" /></a>
52
+ <a href="https://doctordean.github.io/lazarus/"><img src="https://img.shields.io/badge/docs-github.io-0c8f6e" alt="Docs" /></a>
53
+ <a href="https://colab.research.google.com/github/DoctorDean/lazarus/blob/main/notebooks/Lazarus_Democratizing_Dead_SOTA.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab" /></a>
54
+ <img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT" />
55
+ </p>
56
+
57
+ <p align="center"><em>New here? <a href="notebooks/Lazarus_Democratizing_Dead_SOTA.ipynb">Open the notebook in Colab</a> β€” a 2-minute, zero-setup tour (no Docker, no GPU): run the dependency pinner live, inspect the four revived tools, and see the binder-triage result rendered in 3D.</em></p>
58
+
59
+ ---
60
+
61
+ ## The wall
62
+
63
+ Computational science has a reproducibility problem. A huge fraction of published methods
64
+ are **open, cited, and unrunnable** within a few years: the repo is stale, wired to a stack
65
+ that no longer resolves, and the real capability is buried in scripts with no API. If you're
66
+ on a small, budget-constrained ML-for-biology team, you hit this constantly β€” the exact
67
+ method you need exists, but getting it to run costs days you don't have, so it gets abandoned.
68
+
69
+ ## What Lazarus does
70
+
71
+ Lazarus is an agent that **revives** dead research code, lets you **compose** the revivals
72
+ into pipelines, and **gives the fixes back** to the community.
73
+
74
+ 1. **Revive** β€” point it at a **bare GitHub URL**. Lazarus reads the repo and the paper the
75
+ way a newcomer would and **writes its own goal and sanity check**, then runs a
76
+ build β†’ execute β†’ read-traceback β†’ repair loop in a sandbox. Pin dependencies to the
77
+ commit era, resolve the binary chain, locate the real capability, and emit a fixed
78
+ **integration contract**: an importable module, a CLI, a pinned container, and a smoke
79
+ test that proves it runs on a fresh input and passes the sanity check it defined.
80
+ 2. **Compose** β€” because every revival emits the *same* contract, a revived tool is a
81
+ composable **brick**. Wire bricks from any domain/language/era into a pipeline with a
82
+ small YAML; one command runs them, passing artifacts between steps (local / remote / GPU).
83
+ 3. **Give back** β€” the fixes Lazarus finds (rotted URLs, broken paths, a 15-year-old
84
+ undefined-behavior bug) become maintainer-ready **pull requests** with CI, so the method
85
+ can't silently rot again.
86
+
87
+ ## Proof β€” four dead repos, resurrected autonomously
88
+
89
+ Each revived from its own dead environment using only general heuristics (no repo-specific
90
+ notes), each emitting a callable package that passes its **own smoke test standalone**:
91
+
92
+ | Repo | Flavor | Turns | Result on `4ZQK_A` |
93
+ |---|---|:--:|---|
94
+ | **MaSIF-site** ([LPDI-EPFL/masif](https://github.com/LPDI-EPFL/masif)) | Py3.6 Β· TF 1.12 Β· surface + MSMS/APBS (revive-and-carve) | 18 | interaction site, **ROC-AUC 0.9137** |
95
+ | **ScanNet** ([jertubiana/ScanNet](https://github.com/jertubiana/ScanNet)) | Py3.6 Β· TF 1.14 Β· Keras (revive-and-carve) | 19 | binding site, **ROC-AUC 0.9233** |
96
+ | **dMaSIF** ([FreyrS/dMaSIF](https://github.com/FreyrS/dMaSIF)) | Py3.6 Β· torch cu111 Β· PyKeOps Β· **GPU, built from scratch** | 51 | binding site, **ROC-AUC 0.8390** |
97
+ | **fpocket** ([2010 SourceForge](https://fpocket.sourceforge.net/)) | **2010 C**, built on modern GCC β€” a different flavor entirely | 32 | 3 druggable pockets |
98
+
99
+ The dMaSIF run built a whole CUDA/KeOps GPU environment from a bare image and **patched a
100
+ source bug to unlock GPU execution the original forced to CPU**. The fpocket run fought a
101
+ SourceForge download interstitial, a modern-`ld` link-order break, and a **15-year-old
102
+ overlapping-`sprintf` undefined-behavior bug** that modern glibc exposed. Three genuinely
103
+ different resurrection flavors β€” TF/CUDA/C.
104
+
105
+ **Three-way head-to-head** (the three site predictors, scored by one script on identical
106
+ PD-L1 residue labels): **ScanNet 0.915 Β· dMaSIF 0.854 Β· MaSIF 0.823**. All localize the
107
+ interface (a **13-residue consensus core**); the two *surface* methods (MaSIF & dMaSIF)
108
+ agree most (Spearman ρ 0.70). Details: [`analysis/RESULTS.md`](analysis/RESULTS.md).
109
+
110
+ ## Point it at a URL β€” it writes its own plan
111
+
112
+ You don't hand Lazarus a goal; you hand it a link. A web-enabled **Scout** reads the repo
113
+ and paper (and *only* those β€” never your notes) and drafts the whole plan: the capability to
114
+ revive, a base image, and a **falsifiable sanity check**. Then it pauses for your OK before
115
+ spending a turn.
116
+
117
+ ```bash
118
+ lazarus resurrect https://github.com/jertubiana/ScanNet
119
+ ```
120
+
121
+ Run cold against ScanNet with **no hints**, the Scout reconstructed β€” from the URL alone β€” a
122
+ plan matching the one a human expert hand-wrote after days of work:
123
+
124
+ | | Human, after days of setup | Scout, from the URL alone |
125
+ |---|---|---|
126
+ | Capability | per-residue binding-site probabilities | βœ… same |
127
+ | Test input | 4ZQK chain A (PD-L1) | βœ… same |
128
+ | Sanity check | ROC-AUC β‰₯ 0.70 vs the 5 Γ… interface | βœ… **identical** |
129
+ | Base image | *(supplied by hand)* | βœ… found the real `jertubiana/scannet` on Docker Hub |
130
+ | Known traps | issues #14 & #15 (hand-noted) | βœ… **surfaced both unaided** β€” the two we later fixed upstream |
131
+
132
+ That's the democratization step: the expert judgment of *what "revived" even means* becomes
133
+ something you get from pasting a link.
134
+
135
+ **Then we pointed it at a repo we'd never touched, in a different field entirely.** From just
136
+ `github.com/davek44/Basset` β€” a 2016 **Lua Torch7** genomics CNN (chromatin accessibility from DNA
137
+ sequence) β€” the Scout planned it and the agent revived it end to end. Along the way it cleared a
138
+ *new* class of decay (the README's 2016 Docker image ships a manifest modern Docker refuses to pull
139
+ β€” converted with `skopeo`), and caught a **silent scientific-correctness bug**: the naive run scored
140
+ mean AUROC **0.675**, but the agent traced it to hg19's soft-masked lowercase bases falling through
141
+ Basset's uppercase-only one-hot encoder, patched it, and **reproduced the paper β€” mean AUROC 0.8944
142
+ vs 0.895** across all 164 cell types. A fifth brick, a new domain (genomics, not protein surfaces),
143
+ a fourth dead framework β€” from a link. Details: [`docs/CHALLENGES.md`](docs/CHALLENGES.md) Β§5.
144
+
145
+ ## Compose β€” an in-silico pipeline from revived bricks
146
+
147
+ `examples/pipelines/binder_triage.yaml` assembles **methods that were each individually
148
+ unrunnable a week ago** into one binder-triage pipeline:
149
+
150
+ ```
151
+ structure ─▢ ScanNet ─┐
152
+ ─▢ dMaSIF ──┼─▢ consensus ─▢ interface residues that also line a druggable pocket
153
+ ─▢ fpocket β”€β”˜
154
+ ```
155
+
156
+ ```bash
157
+ lazarus run examples/pipelines/binder_triage.yaml \
158
+ --input structure=4ZQK.pdb \
159
+ --registry examples --registry components \
160
+ --docker-host ssh://you@your-x86-gpu-box
161
+ ```
162
+
163
+ Run live on PD-L1, it concluded: **27 interface residues** (115, 123, 56, 121, 113…), but
164
+ **0 druggable pockets** β†’ *"the interface is clearly localized but not a druggable small-
165
+ molecule pocket β€” a flat protein-protein interface, i.e. an antibody/biologic target."*
166
+ That's textbook immuno-oncology (PD-1/PD-L1 *is* an antibody target), reproduced from dead
167
+ code. Sample output: [`examples/pipelines/sample_output_4ZQK/`](examples/pipelines/sample_output_4ZQK/).
168
+
169
+ ## Give back
170
+
171
+ For the genuinely-abandoned repos, Lazarus prepares maintainer-ready PRs β€” the real fix
172
+ plus a **CI smoke test** so it can't silently rot again:
173
+
174
+ - **MaSIF β€” [PR #93](https://github.com/LPDI-EPFL/masif/pull/93)** β€” the rotted PDB download,
175
+ fixed (direct RCSB fetch); verified to revive the built-in flow at ROC-AUC 0.9137. β†’
176
+ [`giveback/masif/`](giveback/masif/)
177
+ - **ScanNet β€” [PR #16](https://github.com/jertubiana/ScanNet/pull/16)** β€” `library_folder=''`
178
+ made to auto-detect the repo root; verified. β†’ [`giveback/scannet/`](giveback/scannet/)
179
+
180
+ (dMaSIF is skipped β€” CC BY-NC-ND, no-derivatives; fpocket's upstream is alive.)
181
+
182
+ ## Reproduces the paper
183
+
184
+ A smoke test proves a method *runs*; a benchmark proves it's *the method*. Lazarus re-ran
185
+ MaSIF-site on its own **transient PPI benchmark** β€” through the built-in download that
186
+ give-back [PR #93](https://github.com/LPDI-EPFL/masif/pull/93) revived β€” and matched the published number:
187
+
188
+ | Metric | Paper (Gainza et al. 2020, n=59) | Lazarus (n=15 slice) |
189
+ |---|:--:|:--:|
190
+ | median per-structure ROC-AUC | **0.85** | **0.82** β†’ **reproduced** (Β±0.05) |
191
+
192
+ Every revival can carry this: the contract's `benchmark` field emits a
193
+ [`REPRODUCE.md`](examples/masif_site_contract/REPRODUCE.md) certificate with a PASS/OFF
194
+ verdict β€” the trust layer that turns a resurrection into something a team will actually adopt.
195
+
196
+ ## How it works β€” five organs
197
+
198
+ | Organ | Role |
199
+ |---|---|
200
+ | **Scout** | Reads a bare repo URL + its paper (web-enabled, but blind to your notes) and drafts the resurrection plan: capability, base image, and a falsifiable sanity check β€” so a revival starts from a link, not a hand-written goal. |
201
+ | **Sandbox** | Disposable container (CPU or GPU); expensive successes are snapshotted so a later failure never re-pays the build. |
202
+ | **Commit-era pinner** | Reconstructs the dependency universe as it was on the repo's last commit β€” the reasoning that beat the cu111/KeOps/`cppyy` tangle. |
203
+ | **Repair loop** | build β†’ run β†’ read traceback β†’ patch β†’ retry, bounded, isolated to the container. |
204
+ | **Capability locator** | Finds where "input β†’ the famous output" happens and carves the minimal path to it. |
205
+ | **Contract emitter** | Module + CLI + pinned container + smoke test β€” CPU or GPU, verified callable on its own. |
206
+
207
+ ## Runs on a laptop, executes anywhere
208
+
209
+ Lazarus runs on your machine; *where it executes* is pluggable via one flag β€” a local
210
+ container, a remote x86 box, a **cloud VM**, or a **GPU rental** β€” for methods (like MaSIF's
211
+ MSMS or dMaSIF's CUDA) whose binaries need hardware laptop emulation can't provide. The
212
+ agent's tools and the emitted `predict.py` both run against whatever `--docker-host` /
213
+ `DOCKER_HOST` points at, so the whole chain is host-agnostic.
214
+
215
+ ## Quickstart
216
+
217
+ ```bash
218
+ pip install lazarus-bio # the tooling: pinner, compose, contracts
219
+ pip install "lazarus-bio[agent]" # + the autonomous revive loop & Scout (Python β‰₯ 3.10 + Docker)
220
+ # or, to hack on Lazarus itself:
221
+ # git clone https://github.com/DoctorDean/lazarus && cd lazarus
222
+ # pip install -e ".[dev,agent]"
223
+
224
+ # commit-era dependency pinning β€” no repo execution required
225
+ lazarus pin --date 2019-01-01 tensorflow numpy scipy
226
+ # tensorflow==1.12.0 (matches MaSIF's real Dockerfile, not its README)
227
+
228
+ # resurrect straight from a URL β€” the Scout writes the goal + picks the image,
229
+ # then pauses for your OK before spending compute (needs Docker + Claude auth)
230
+ lazarus resurrect https://github.com/jertubiana/ScanNet
231
+
232
+ # …or drive it by hand with an explicit image + goal (both override the Scout)
233
+ lazarus resurrect --image pablogainza/masif:latest --workdir /masif \
234
+ --goal-file examples/masif_site_goal.txt --keep
235
+
236
+ # compose revived components into a pipeline
237
+ lazarus run examples/pipelines/binder_triage.yaml --input structure=4ZQK.pdb \
238
+ --registry examples --registry components
239
+ ```
240
+
241
+ **Auth:** Lazarus drives Claude via the [Claude Agent SDK](https://github.com/anthropics/claude-agent-sdk-python).
242
+ Log in the `claude` CLI (subscription) or put `ANTHROPIC_API_KEY=...` in a gitignored `.env`.
243
+
244
+ ## Status
245
+
246
+ Working today: **Scout** (URL β†’ resurrection plan) Β· pinner Β· Docker sandbox (local + `ssh://`
247
+ remote + `--gpus`) Β· autonomous repair loop Β· capability locator Β· contract emitter (GPU-aware,
248
+ with reproduction certificates) Β· **Lazarus Compose**. All three pillars landed β€” **five** dead
249
+ repos revived (four protein + one genomics, the fifth from nothing but a URL), a three-way method
250
+ comparison, a live binder-triage pipeline, two reproduced paper benchmarks, and two give-back
251
+ PRs β€” with 49 passing tests.
252
+
253
+ **Two front doors:** a [zero-setup Colab notebook](notebooks/Lazarus_Democratizing_Dead_SOTA.ipynb)
254
+ for newcomers (no Docker/GPU β€” pinner live + the result rendered in 3D), and a
255
+ [3-minute demo-video script](docs/DEMO_SCRIPT.md) for the live-compute story (autonomous
256
+ revival + the pipeline running on a GPU box).
257
+
258
+ ## License
259
+
260
+ MIT β€” see [LICENSE](LICENSE).
@@ -0,0 +1,223 @@
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/DoctorDean/lazarus/main/lazarus.png" width="440" alt="Lazarus β€” resurrecting a dead repo" />
3
+ </p>
4
+
5
+ <h1 align="center">Lazarus</h1>
6
+
7
+ <p align="center"><em>Turn dead research code into a callable pipeline component β€” and give the revival back.</em></p>
8
+
9
+ <p align="center">
10
+ 🧬 <strong>Build track</strong> · Built with <strong>Claude Science</strong> hackathon · July 2026
11
+ </p>
12
+
13
+ <p align="center">
14
+ <a href="https://pypi.org/project/lazarus-bio/"><img src="https://img.shields.io/pypi/v/lazarus-bio?color=0c8f6e" alt="PyPI" /></a>
15
+ <a href="https://doctordean.github.io/lazarus/"><img src="https://img.shields.io/badge/docs-github.io-0c8f6e" alt="Docs" /></a>
16
+ <a href="https://colab.research.google.com/github/DoctorDean/lazarus/blob/main/notebooks/Lazarus_Democratizing_Dead_SOTA.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab" /></a>
17
+ <img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT" />
18
+ </p>
19
+
20
+ <p align="center"><em>New here? <a href="notebooks/Lazarus_Democratizing_Dead_SOTA.ipynb">Open the notebook in Colab</a> β€” a 2-minute, zero-setup tour (no Docker, no GPU): run the dependency pinner live, inspect the four revived tools, and see the binder-triage result rendered in 3D.</em></p>
21
+
22
+ ---
23
+
24
+ ## The wall
25
+
26
+ Computational science has a reproducibility problem. A huge fraction of published methods
27
+ are **open, cited, and unrunnable** within a few years: the repo is stale, wired to a stack
28
+ that no longer resolves, and the real capability is buried in scripts with no API. If you're
29
+ on a small, budget-constrained ML-for-biology team, you hit this constantly β€” the exact
30
+ method you need exists, but getting it to run costs days you don't have, so it gets abandoned.
31
+
32
+ ## What Lazarus does
33
+
34
+ Lazarus is an agent that **revives** dead research code, lets you **compose** the revivals
35
+ into pipelines, and **gives the fixes back** to the community.
36
+
37
+ 1. **Revive** β€” point it at a **bare GitHub URL**. Lazarus reads the repo and the paper the
38
+ way a newcomer would and **writes its own goal and sanity check**, then runs a
39
+ build β†’ execute β†’ read-traceback β†’ repair loop in a sandbox. Pin dependencies to the
40
+ commit era, resolve the binary chain, locate the real capability, and emit a fixed
41
+ **integration contract**: an importable module, a CLI, a pinned container, and a smoke
42
+ test that proves it runs on a fresh input and passes the sanity check it defined.
43
+ 2. **Compose** β€” because every revival emits the *same* contract, a revived tool is a
44
+ composable **brick**. Wire bricks from any domain/language/era into a pipeline with a
45
+ small YAML; one command runs them, passing artifacts between steps (local / remote / GPU).
46
+ 3. **Give back** β€” the fixes Lazarus finds (rotted URLs, broken paths, a 15-year-old
47
+ undefined-behavior bug) become maintainer-ready **pull requests** with CI, so the method
48
+ can't silently rot again.
49
+
50
+ ## Proof β€” four dead repos, resurrected autonomously
51
+
52
+ Each revived from its own dead environment using only general heuristics (no repo-specific
53
+ notes), each emitting a callable package that passes its **own smoke test standalone**:
54
+
55
+ | Repo | Flavor | Turns | Result on `4ZQK_A` |
56
+ |---|---|:--:|---|
57
+ | **MaSIF-site** ([LPDI-EPFL/masif](https://github.com/LPDI-EPFL/masif)) | Py3.6 Β· TF 1.12 Β· surface + MSMS/APBS (revive-and-carve) | 18 | interaction site, **ROC-AUC 0.9137** |
58
+ | **ScanNet** ([jertubiana/ScanNet](https://github.com/jertubiana/ScanNet)) | Py3.6 Β· TF 1.14 Β· Keras (revive-and-carve) | 19 | binding site, **ROC-AUC 0.9233** |
59
+ | **dMaSIF** ([FreyrS/dMaSIF](https://github.com/FreyrS/dMaSIF)) | Py3.6 Β· torch cu111 Β· PyKeOps Β· **GPU, built from scratch** | 51 | binding site, **ROC-AUC 0.8390** |
60
+ | **fpocket** ([2010 SourceForge](https://fpocket.sourceforge.net/)) | **2010 C**, built on modern GCC β€” a different flavor entirely | 32 | 3 druggable pockets |
61
+
62
+ The dMaSIF run built a whole CUDA/KeOps GPU environment from a bare image and **patched a
63
+ source bug to unlock GPU execution the original forced to CPU**. The fpocket run fought a
64
+ SourceForge download interstitial, a modern-`ld` link-order break, and a **15-year-old
65
+ overlapping-`sprintf` undefined-behavior bug** that modern glibc exposed. Three genuinely
66
+ different resurrection flavors β€” TF/CUDA/C.
67
+
68
+ **Three-way head-to-head** (the three site predictors, scored by one script on identical
69
+ PD-L1 residue labels): **ScanNet 0.915 Β· dMaSIF 0.854 Β· MaSIF 0.823**. All localize the
70
+ interface (a **13-residue consensus core**); the two *surface* methods (MaSIF & dMaSIF)
71
+ agree most (Spearman ρ 0.70). Details: [`analysis/RESULTS.md`](analysis/RESULTS.md).
72
+
73
+ ## Point it at a URL β€” it writes its own plan
74
+
75
+ You don't hand Lazarus a goal; you hand it a link. A web-enabled **Scout** reads the repo
76
+ and paper (and *only* those β€” never your notes) and drafts the whole plan: the capability to
77
+ revive, a base image, and a **falsifiable sanity check**. Then it pauses for your OK before
78
+ spending a turn.
79
+
80
+ ```bash
81
+ lazarus resurrect https://github.com/jertubiana/ScanNet
82
+ ```
83
+
84
+ Run cold against ScanNet with **no hints**, the Scout reconstructed β€” from the URL alone β€” a
85
+ plan matching the one a human expert hand-wrote after days of work:
86
+
87
+ | | Human, after days of setup | Scout, from the URL alone |
88
+ |---|---|---|
89
+ | Capability | per-residue binding-site probabilities | βœ… same |
90
+ | Test input | 4ZQK chain A (PD-L1) | βœ… same |
91
+ | Sanity check | ROC-AUC β‰₯ 0.70 vs the 5 Γ… interface | βœ… **identical** |
92
+ | Base image | *(supplied by hand)* | βœ… found the real `jertubiana/scannet` on Docker Hub |
93
+ | Known traps | issues #14 & #15 (hand-noted) | βœ… **surfaced both unaided** β€” the two we later fixed upstream |
94
+
95
+ That's the democratization step: the expert judgment of *what "revived" even means* becomes
96
+ something you get from pasting a link.
97
+
98
+ **Then we pointed it at a repo we'd never touched, in a different field entirely.** From just
99
+ `github.com/davek44/Basset` β€” a 2016 **Lua Torch7** genomics CNN (chromatin accessibility from DNA
100
+ sequence) β€” the Scout planned it and the agent revived it end to end. Along the way it cleared a
101
+ *new* class of decay (the README's 2016 Docker image ships a manifest modern Docker refuses to pull
102
+ β€” converted with `skopeo`), and caught a **silent scientific-correctness bug**: the naive run scored
103
+ mean AUROC **0.675**, but the agent traced it to hg19's soft-masked lowercase bases falling through
104
+ Basset's uppercase-only one-hot encoder, patched it, and **reproduced the paper β€” mean AUROC 0.8944
105
+ vs 0.895** across all 164 cell types. A fifth brick, a new domain (genomics, not protein surfaces),
106
+ a fourth dead framework β€” from a link. Details: [`docs/CHALLENGES.md`](docs/CHALLENGES.md) Β§5.
107
+
108
+ ## Compose β€” an in-silico pipeline from revived bricks
109
+
110
+ `examples/pipelines/binder_triage.yaml` assembles **methods that were each individually
111
+ unrunnable a week ago** into one binder-triage pipeline:
112
+
113
+ ```
114
+ structure ─▢ ScanNet ─┐
115
+ ─▢ dMaSIF ──┼─▢ consensus ─▢ interface residues that also line a druggable pocket
116
+ ─▢ fpocket β”€β”˜
117
+ ```
118
+
119
+ ```bash
120
+ lazarus run examples/pipelines/binder_triage.yaml \
121
+ --input structure=4ZQK.pdb \
122
+ --registry examples --registry components \
123
+ --docker-host ssh://you@your-x86-gpu-box
124
+ ```
125
+
126
+ Run live on PD-L1, it concluded: **27 interface residues** (115, 123, 56, 121, 113…), but
127
+ **0 druggable pockets** β†’ *"the interface is clearly localized but not a druggable small-
128
+ molecule pocket β€” a flat protein-protein interface, i.e. an antibody/biologic target."*
129
+ That's textbook immuno-oncology (PD-1/PD-L1 *is* an antibody target), reproduced from dead
130
+ code. Sample output: [`examples/pipelines/sample_output_4ZQK/`](examples/pipelines/sample_output_4ZQK/).
131
+
132
+ ## Give back
133
+
134
+ For the genuinely-abandoned repos, Lazarus prepares maintainer-ready PRs β€” the real fix
135
+ plus a **CI smoke test** so it can't silently rot again:
136
+
137
+ - **MaSIF β€” [PR #93](https://github.com/LPDI-EPFL/masif/pull/93)** β€” the rotted PDB download,
138
+ fixed (direct RCSB fetch); verified to revive the built-in flow at ROC-AUC 0.9137. β†’
139
+ [`giveback/masif/`](giveback/masif/)
140
+ - **ScanNet β€” [PR #16](https://github.com/jertubiana/ScanNet/pull/16)** β€” `library_folder=''`
141
+ made to auto-detect the repo root; verified. β†’ [`giveback/scannet/`](giveback/scannet/)
142
+
143
+ (dMaSIF is skipped β€” CC BY-NC-ND, no-derivatives; fpocket's upstream is alive.)
144
+
145
+ ## Reproduces the paper
146
+
147
+ A smoke test proves a method *runs*; a benchmark proves it's *the method*. Lazarus re-ran
148
+ MaSIF-site on its own **transient PPI benchmark** β€” through the built-in download that
149
+ give-back [PR #93](https://github.com/LPDI-EPFL/masif/pull/93) revived β€” and matched the published number:
150
+
151
+ | Metric | Paper (Gainza et al. 2020, n=59) | Lazarus (n=15 slice) |
152
+ |---|:--:|:--:|
153
+ | median per-structure ROC-AUC | **0.85** | **0.82** β†’ **reproduced** (Β±0.05) |
154
+
155
+ Every revival can carry this: the contract's `benchmark` field emits a
156
+ [`REPRODUCE.md`](examples/masif_site_contract/REPRODUCE.md) certificate with a PASS/OFF
157
+ verdict β€” the trust layer that turns a resurrection into something a team will actually adopt.
158
+
159
+ ## How it works β€” five organs
160
+
161
+ | Organ | Role |
162
+ |---|---|
163
+ | **Scout** | Reads a bare repo URL + its paper (web-enabled, but blind to your notes) and drafts the resurrection plan: capability, base image, and a falsifiable sanity check β€” so a revival starts from a link, not a hand-written goal. |
164
+ | **Sandbox** | Disposable container (CPU or GPU); expensive successes are snapshotted so a later failure never re-pays the build. |
165
+ | **Commit-era pinner** | Reconstructs the dependency universe as it was on the repo's last commit β€” the reasoning that beat the cu111/KeOps/`cppyy` tangle. |
166
+ | **Repair loop** | build β†’ run β†’ read traceback β†’ patch β†’ retry, bounded, isolated to the container. |
167
+ | **Capability locator** | Finds where "input β†’ the famous output" happens and carves the minimal path to it. |
168
+ | **Contract emitter** | Module + CLI + pinned container + smoke test β€” CPU or GPU, verified callable on its own. |
169
+
170
+ ## Runs on a laptop, executes anywhere
171
+
172
+ Lazarus runs on your machine; *where it executes* is pluggable via one flag β€” a local
173
+ container, a remote x86 box, a **cloud VM**, or a **GPU rental** β€” for methods (like MaSIF's
174
+ MSMS or dMaSIF's CUDA) whose binaries need hardware laptop emulation can't provide. The
175
+ agent's tools and the emitted `predict.py` both run against whatever `--docker-host` /
176
+ `DOCKER_HOST` points at, so the whole chain is host-agnostic.
177
+
178
+ ## Quickstart
179
+
180
+ ```bash
181
+ pip install lazarus-bio # the tooling: pinner, compose, contracts
182
+ pip install "lazarus-bio[agent]" # + the autonomous revive loop & Scout (Python β‰₯ 3.10 + Docker)
183
+ # or, to hack on Lazarus itself:
184
+ # git clone https://github.com/DoctorDean/lazarus && cd lazarus
185
+ # pip install -e ".[dev,agent]"
186
+
187
+ # commit-era dependency pinning β€” no repo execution required
188
+ lazarus pin --date 2019-01-01 tensorflow numpy scipy
189
+ # tensorflow==1.12.0 (matches MaSIF's real Dockerfile, not its README)
190
+
191
+ # resurrect straight from a URL β€” the Scout writes the goal + picks the image,
192
+ # then pauses for your OK before spending compute (needs Docker + Claude auth)
193
+ lazarus resurrect https://github.com/jertubiana/ScanNet
194
+
195
+ # …or drive it by hand with an explicit image + goal (both override the Scout)
196
+ lazarus resurrect --image pablogainza/masif:latest --workdir /masif \
197
+ --goal-file examples/masif_site_goal.txt --keep
198
+
199
+ # compose revived components into a pipeline
200
+ lazarus run examples/pipelines/binder_triage.yaml --input structure=4ZQK.pdb \
201
+ --registry examples --registry components
202
+ ```
203
+
204
+ **Auth:** Lazarus drives Claude via the [Claude Agent SDK](https://github.com/anthropics/claude-agent-sdk-python).
205
+ Log in the `claude` CLI (subscription) or put `ANTHROPIC_API_KEY=...` in a gitignored `.env`.
206
+
207
+ ## Status
208
+
209
+ Working today: **Scout** (URL β†’ resurrection plan) Β· pinner Β· Docker sandbox (local + `ssh://`
210
+ remote + `--gpus`) Β· autonomous repair loop Β· capability locator Β· contract emitter (GPU-aware,
211
+ with reproduction certificates) Β· **Lazarus Compose**. All three pillars landed β€” **five** dead
212
+ repos revived (four protein + one genomics, the fifth from nothing but a URL), a three-way method
213
+ comparison, a live binder-triage pipeline, two reproduced paper benchmarks, and two give-back
214
+ PRs β€” with 49 passing tests.
215
+
216
+ **Two front doors:** a [zero-setup Colab notebook](notebooks/Lazarus_Democratizing_Dead_SOTA.ipynb)
217
+ for newcomers (no Docker/GPU β€” pinner live + the result rendered in 3D), and a
218
+ [3-minute demo-video script](docs/DEMO_SCRIPT.md) for the live-compute story (autonomous
219
+ revival + the pipeline running on a GPU box).
220
+
221
+ ## License
222
+
223
+ MIT β€” see [LICENSE](LICENSE).
@@ -0,0 +1,59 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "lazarus-bio"
7
+ version = "0.1.0"
8
+ description = "Resurrect dead research code into a callable pipeline component β€” and give the revival back."
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = { text = "MIT" }
12
+ authors = [{ name = "Dean Sherry", email = "dean.shez@gmail.com" }]
13
+ keywords = [
14
+ "bioinformatics",
15
+ "reproducibility",
16
+ "agents",
17
+ "dependency-pinning",
18
+ "research-software",
19
+ "docker",
20
+ ]
21
+ classifiers = [
22
+ "Development Status :: 4 - Beta",
23
+ "Intended Audience :: Science/Research",
24
+ "Intended Audience :: Developers",
25
+ "License :: OSI Approved :: MIT License",
26
+ "Operating System :: OS Independent",
27
+ "Programming Language :: Python :: 3",
28
+ "Programming Language :: Python :: 3.9",
29
+ "Programming Language :: Python :: 3.10",
30
+ "Programming Language :: Python :: 3.11",
31
+ "Programming Language :: Python :: 3.12",
32
+ "Topic :: Scientific/Engineering :: Bio-Informatics",
33
+ "Topic :: Software Development :: Build Tools",
34
+ ]
35
+ dependencies = [
36
+ "packaging>=21",
37
+ "PyYAML>=6",
38
+ ]
39
+
40
+ [project.optional-dependencies]
41
+ dev = ["pytest>=7", "build>=1", "twine>=5"]
42
+ # The autonomous loop + Scout need the Claude Agent SDK (Python >= 3.10).
43
+ agent = ["claude-agent-sdk>=0.2"]
44
+
45
+ [project.urls]
46
+ Homepage = "https://github.com/DoctorDean/lazarus"
47
+ Documentation = "https://doctordean.github.io/lazarus/"
48
+ Repository = "https://github.com/DoctorDean/lazarus"
49
+ Issues = "https://github.com/DoctorDean/lazarus/issues"
50
+ "Try in Colab" = "https://colab.research.google.com/github/DoctorDean/lazarus/blob/main/notebooks/Lazarus_Democratizing_Dead_SOTA.ipynb"
51
+
52
+ [project.scripts]
53
+ lazarus = "lazarus.cli:main"
54
+
55
+ [tool.setuptools.packages.find]
56
+ where = ["src"]
57
+
58
+ [tool.pytest.ini_options]
59
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,52 @@
1
+ """Lazarus β€” turn dead research code into a callable pipeline component.
2
+
3
+ Lazarus clones a stale repo, reads its paper for intent, and runs a
4
+ build -> execute -> read-traceback -> repair loop in a sandbox. It pins
5
+ dependencies to the repo's commit era, resolves external-binary chains,
6
+ locates the real capability buried in the scripts, and emits a fixed
7
+ integration contract: an importable module, a CLI, a pinned container, and
8
+ a smoke test that proves the method runs on a fresh input.
9
+ """
10
+
11
+ from importlib.metadata import PackageNotFoundError, version as _pkg_version
12
+
13
+ try: # single source of truth is the installed package metadata (pyproject)
14
+ __version__ = _pkg_version("lazarus-bio")
15
+ except PackageNotFoundError: # running from a source tree that isn't installed
16
+ __version__ = "0.1.0"
17
+
18
+ from lazarus.pinner import (
19
+ ReleaseInfo,
20
+ fetch_release_history,
21
+ pin_package,
22
+ pin_requirements,
23
+ select_version,
24
+ )
25
+ from lazarus.sandbox import (
26
+ CommandResult,
27
+ DockerClient,
28
+ DockerError,
29
+ Sandbox,
30
+ )
31
+ from lazarus.contract import (
32
+ Benchmark,
33
+ Contract,
34
+ IOSpec,
35
+ SmokeCheck,
36
+ emit,
37
+ )
38
+
39
+ __all__ = [
40
+ "__version__",
41
+ # pinner
42
+ "ReleaseInfo",
43
+ "fetch_release_history",
44
+ "pin_package",
45
+ "pin_requirements",
46
+ "select_version",
47
+ # sandbox
48
+ "CommandResult",
49
+ "DockerClient",
50
+ "DockerError",
51
+ "Sandbox",
52
+ ]