b0cb6280d7
- db/pg_migrate.py: asyncpg migration runner with _pg_migrations tracking table, ordered .sql, transactional, 3x retry on connection failure (R-MT-02). - db/pg_schema.sql + db/pg_migrations/0001_operator_tier.sql: 5 operator-tier tables (operators, issued_credentials, mastery_gate_events, cohort_aggregates, issuer_keys) using gen_random_uuid() (PG16 core, no extension). cohort_aggregates is a plain table, NOT partitioned (D-050). - db/pg_store.py: PgStore class implementing the IssuerKeyStore protocol (init/get_active/get_public_key_row/set_superseded) plus operator CRUD, cohort aggregate read/write, credential methods, gate events. get_public_key_row queries by id (not status) → finds superseded keys (R-VC-MIG-01 verification fallback, D-051). No cross-DB FKs (D-031). - tests/test_pg_store.py: 13 integration tests (skip if PRAXIS_PG_DSN unset). ---ci--- project: praxis phase: 1 milestone: v0.4 status: execute persona: data-engineer task: 01-04,01-05,01-06,01-07 requirements: covered: [REQ-MT-01, REQ-NFR-MT-01, REQ-MT-02] ---/ci---