### Orchestrator Persistence Module (MVP) This document summarizes the initial implementation of a persistence layer for the Orchestrator. Scope (MVP): - Introduces a new `persist` module under `crates/orchestrator/src/persist.rs`. - Provides optional, best-effort database initialization using SeaORM for Postgres. - Applies workspace migrations from `crates/migration` when a database is available. - Exposes a small API surface intended for Orchestrator use: - `Persist::new(database_url: Option) -> Result` — connect and run migrations; falls back to no-op mode if unavailable. - `Persist::is_enabled() -> bool` — indicates whether DB is active. - `Persist::record_job_state(...)` — placeholder for recording job state transitions. - `Persist::record_vm_event(...)` — placeholder for VM lifecycle events. Design Notes: - The API currently logs no-op actions if `DATABASE_URL` is unset or connection/migration fails, allowing the Orchestrator to run without a DB (useful for local development and CI). - Actual inserts/updates are intentionally left as stubs to keep this MVP minimal and non-invasive. Follow-up work will add SeaORM Entities (Jobs/VMs) mirroring the `crates/migration` schema and implement these calls. - Migrations are sourced from the new `migration` crate already present in the workspace. The orchestrator now depends on `sea-orm-migration` and `migration` to run these on startup when enabled. Schema Reference (from `crates/migration`): - `jobs`: `request_id (uuid pk)`, `repo_url (text)`, `commit_sha (text)`, `runs_on (text null)`, `state (text)`, `created_at (timestamptz)`, `updated_at (timestamptz)` - `vms`: `request_id (uuid)`, `domain_name (text)`, `overlay_path (text null)`, `seed_path (text null)`, `backend (text)`, `state (text)`, `created_at (timestamptz)`, `updated_at (timestamptz)` Configuration: - `DATABASE_URL=postgres://user:pass@host:5432/solstice` - If set, the orchestrator can initialize persistence via `Persist::new(Some(DATABASE_URL))`. - If not set or connection fails, the module operates in no-op mode. Next Steps: - Implement SeaORM Entities for `jobs` and `vms` and wire `record_job_state` / `record_vm_event` to real upserts. - Call persistence hooks from the scheduler around VM prepare/start/stop/destroy and from the consumer when accepting jobs. - Add unit/integration tests with a test Postgres (or use SeaORM SQLite feature for fast tests, if acceptable).