Adds `mosaic storage migrate-tier --to federated` for one-way migration
from `local` (PGlite) or `standalone` (PG without pgvector) to
`federated` (PG + pgvector). Source is read via DrizzleMigrationSource
which queries the normalized schema (the same path the gateway writes
through), so the migration captures all real domain data — not just
the flat key/value collections.
Key behaviors:
- `--dry-run` prints per-table row counts without writes
- `--allow-non-empty` required to write into a populated target (default
refuses to mix data sets)
- Per-table transactions; partial failure does not leave half-migrated
tables
- Idempotent on re-run via INSERT ... ON CONFLICT DO UPDATE keyed on id
- Topological table order respects FK dependencies (verified against
schema.references())
- Skips sessions, verifications, admin_tokens (TTL'd / one-time / env-bound)
- For sources without pgvector, insights.embedding is projected to NULL
on read, then upserted as NULL (column is nullable)
32 unit tests cover ordering, dry-run, idempotency, empty-target
preconditions, table skipping, and embedding-null projection. Integration
test against real PG/PGlite is FED-M1-08.
Refs #460