## Problem

An app on MySQL can use the explicit persistence factories but not `AuthPersistence.make(auth).managed(...)`: `@yielded/auth-persistence` rejects the `mysql` dialect, and `/Mysql2` exports no `AuthPersistence` facade. Every MySQL app must hand-wire the password, session, pending, proof, and registration service graph.

## Evidence

`@yielded/auth-persistence-drizzle@0.1.0-beta.47`:

```ts
import { AuthPersistence } from "@yielded/auth-persistence-drizzle/Mysql2";
// TS2305: Module '"@yielded/auth-persistence-drizzle/Mysql2"'
// has no exported member 'AuthPersistence'
```

`@yielded/auth-persistence` only recognises `pg` and `sqlite` in the composed layer:

```ts
const dialect = client.onDialectOrElse({
  pg: () => "pg",
  sqlite: () => "sqlite",
  orElse: () => undefined,
});
```

So this normal composition fails with `Use an explicit adapter for this SQL dialect`:

```ts
export const Persistence = AuthPersistence.make(AppAuth);
export const storage = Persistence.managed({
  subjects: { table: users, id: "id", status: "disabled", ... },
  prefix: "auth",
});
```

`/Mysql2` currently exports the explicit factories, but not `managed`, `map`, `Config`, `layer`, or `migrationsLayer`. A local patch adding a MySQL backend plus `mysql: () => "mysql"` to the dialect gate makes the same composition work, but carrying a fork of a security package is not a viable long-term answer.

A working patch and real-world composition are in https://github.com/oscartbeaumont/mattraxe/pull/3 (Mattrax on Cloudflare Workers + Hyperdrive MySQL). Happy to turn it into an upstream PR.

## Impact

This blocks MySQL, MariaDB, PlanetScale, and Hyperdrive MySQL as first-class storage for any app using password sign-in and stateful sessions. The alternatives are a 3–5 day hand-wiring of every persistence service or maintaining a patched auth package.

This is not the same surface as #292 (`OAuthServerPersistence`); this is the composed password/session persistence path.

## Proposal

- Export `AuthPersistence` from `/Mysql2`, mirroring `/Postgres`.
- Accept `mysql` in the composed persistence dialect gate.
- Add a MySQL backend for managed/mapped tables with bounded `VARCHAR` keys and millisecond timestamps.
- Decide the MySQL transaction owner: the composed path currently falls back to `sql.withTransaction` (`REPEATABLE READ`), while the explicit MySQL adapters use `mysqlNativeCommit` (`READ COMMITTED`).
- Validate `validateStorageBatch("mysql", ...)` against a live MySQL 8 schema, including the 3072-byte index limit.

<sub>Generated on _MrBeast_ using _opencode-go/deepseek-v4.1-flash_ in _ses_e40ce88e1ffeF7Lm7SQ9QEOKIr_</sub>
