-- Phase 7: keep lease-expiry recovery's scan O(live instances), not O(all).
--
-- recover() selects non-terminal instances:
--   WHERE saga_name = $1 [AND shard_id = ANY($2)] AND status IN ('not-started','running')
-- The existing idx_saga_instances_recovery leads with (saga_name, shard_id,
-- status, updated_at); but as a service runs, TERMINAL rows accumulate without
-- bound (there is no instance GC), and a non-partial index still has to wade
-- past them. A PARTIAL index over only the live statuses contains just the
-- handful of in-flight instances, so the recovery scan stays fast no matter how
-- many completed bookings sit in the table — the same trick es_saga_outbox uses
-- for `published_at IS NULL`. (This bit the stress suite as a transient
-- slow-down once the shared tables bloated; in production it's the difference
-- between recovery staying snappy and degrading with lifetime volume.)
--
-- Append-only migration (009); idempotent.
CREATE INDEX IF NOT EXISTS idx_saga_instances_live
    ON es_saga_instances (saga_name, shard_id)
    WHERE status IN ('not-started', 'running');
