Phase 0, task 0.9b — persistence, the second piece of the vertical slice (after 0.9a provenance, #80).
Scope
Per ADR-004 and ADR-007:
- SQLAlchemy 2.0 models for
run_set, run, run_config, job, result_artifact, dataset_version.
- Alembic from the first migration, on SQLite — so moving to Postgres is a connection-string change rather than a rewrite. No SQLite-specific SQL, no reliance on its type affinity, no
AUTOINCREMENT quirks.
- Artefacts stay on disk behind an interface — a directory today, MinIO or S3 later without touching callers. The database stores paths and checksums, never blobs.
- Job state lives in the database, not in memory, so a handle survives an API restart (ADR-007 notes the in-process pool works without a broker because the API owns it — but the state must outlive the process).
Constraints
- A submitted config is immutable (ADR-004); an edit produces a new config and a new run. The store must not offer an update path that violates that.
config_hash is the identity and the cache key (ADR-006) — indexed, and a run's provenance record is stored with it.
- SQLite's single-writer model is real: job-state writes must be short transactions.
studio/store may import studio.schema / studio.resolve, and must not import coupled.
Base branch: studio/dev.
Phase 0, task 0.9b — persistence, the second piece of the vertical slice (after 0.9a provenance, #80).
Scope
Per ADR-004 and ADR-007:
run_set,run,run_config,job,result_artifact,dataset_version.AUTOINCREMENTquirks.Constraints
config_hashis the identity and the cache key (ADR-006) — indexed, and a run's provenance record is stored with it.studio/storemay importstudio.schema/studio.resolve, and must not importcoupled.Base branch:
studio/dev.