feat(pipeline): stateful, resumable study store + runner (+ bibliography study)#11
Merged
juniperbevensee merged 2 commits intoJun 22, 2026
Merged
Conversation
…phy study) Long analyses currently run inline in one agent turn — they die on OOM and lose all state on container rebuild. This adds durable, checkpointed analysis state so a study resumes from the last completed step instead of vanishing. - engine/store.py: StudyStore (stdlib sqlite3, WAL, atomic). studies/steps/ artifacts/findings tables; create/get/list studies, add_steps, step status + result, artifacts, findings, study_summary. Injected db path (MATILDE_STUDY_DB / HERMES_HOME / repo engagements dir). State survives a fresh StudyStore instance on the same file (the container-rebuild guarantee, under test). - engine/pipeline.py: resumable runner. Step/StepContext/StepResult; run()/resume() skip done steps, persist result+artifacts+findings per step, stop on failure leaving the study blocked + resumable. Pure/injected. - engine/bibliography_study.py: first concrete study (parse_refs -> verify_each -> summarize) reusing the citations/parsing engine, verifier injected. verify_each is mid-step resumable (skips refs that already have findings). - tools.py / __init__.py: matilde_study_create/run/status/list, matching the existing tool-dict + thin-handler conventions. Tests (TDD): store CRUD + status transitions + persistence across a new instance; runner skip-done / stop-on-failure / resume-without-rerun; bibliography happy path and fail-on-ref-#3-then-resume (refs 1-2 NOT re-verified); tool arg coercion + output shape. Full suite: 123 passed, 6 skipped. Engine stays stdlib-only (no mne/numpy) — the heavy MEG data-analysis study is a documented follow-up. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ident specifics); note plan-evolution semantics Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
juniperbevensee
added a commit
to NimbleCoAI/hermes-swarm-map
that referenced
this pull request
Jun 22, 2026
…study pipeline) (#108) v0.3.0 adds the resumable StudyStore + pipeline runner + matilde_study_* tools (NimbleCoOrg/Matilde#11). Reapply to deployed Matilde to expose the new tools. Co-authored-by: Juniper Bevensee <juniperbevensee@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Long analyses (e.g. validating a paper's findings against an OpenNeuro dataset) currently run inline in a single agent turn. Two failure modes, observed live:
Both have the same remedy: durable, checkpointed analysis state so an analysis resumes from the last completed step after an OOM or a container rebuild, instead of vanishing. Spec:
docs/stateful-study-pipeline.md.What's included
matilde_plugin/engine/store.py—StudyStore(stdlibsqlite3, WAL, autocommit/atomic). Tables:studies / steps / artifacts / findings. API:create_study(idempotent on slug),get_study,list_studies,add_steps,set_step_status,record_step_result,add_artifact,add_finding,get_findings,study_summary. Artifacts reference on-disk files, never blobs. Injected db path (MATILDE_STUDY_DB→$HERMES_HOME/engagements→ repoengagements/), so state lives on the mounted data volume.matilde_plugin/engine/pipeline.py— resumable runner.Step / StepContext / StepResult;run(store, study_id, steps, resume=True)skipsdonesteps, marksrunning→done, persists result+artifacts+findings after each step, and on exception marks the stepfailed, the studyblocked, and stops (resumable).resume()continues from the first non-donestep. Pure/injected — testable with in-memory fake steps.matilde_plugin/engine/bibliography_study.py— first concrete study (parse_refs → verify_each → summarize) reusing the existing citations/parsing engine, with the per-reference verifier injected.verify_eachis mid-step resumable (skips refs that already have a persisted finding).matilde_plugin/tools.py+ wiring in__init__.py:matilde_study_create,matilde_study_run,matilde_study_status,matilde_study_list— matching the file's existing tool-dict + thin-handler conventions. Handlers stay thin; logic lives instore.py/pipeline.py.Resumability test evidence
tests/test_store.py::test_state_survives_fresh_store_instance— writes state, drops the connection, opens a newStudyStoreon the same file, and reads everything back (the container-rebuild guarantee).tests/test_pipeline.py::test_resume_continues_from_first_non_done_without_rerunning— first pass fails at stepb; a workingbis swapped in;resumere-runs onlyb+c(a side-effect counter provesais not re-run).tests/test_bibliography_study.py::test_fail_then_resume_does_not_reverify_done_refs— verifier fails on ref OpenNeuro/BIDS dataset client + agent tools (discovery, metadata, files) #3 → studyblocked, refs 1–2 recorded as findings → swap in a working verifier →resume→ studydone, and only ref OpenNeuro/BIDS dataset client + agent tools (discovery, metadata, files) #3 is re-verified (refs 1–2 not re-checked).Verification
.venv/bin/python -m pytest -q→ 123 passed, 6 skipped (baseline was 93+6; +30 new tests).scripts/check_sanitization.py) on changed content files: clean (deterministic layer; semantic layer skips locally withoutANTHROPIC_API_KEY, as designed — CI runs it with the key).mne/numpy/heavy deps added (git diffimports:json, os, sqlite3, time, dataclasses, typing+ intra-package relative imports).Follow-up (out of scope)
The heavy MEG data-analysis study (
fetch_dataset → preprocess → epoch → evoked → validate_finding, memory-bounded, intermediates checkpointed as artifacts) is a documented follow-up — it needs the agent container memory budget decided and wheremneis installed. This PR is the framework + a lightweight first study that proves it.Please do not merge — left open for independent audit.
🤖 Generated with Claude Code