NpgsqlRetryingExecutionStrategy rejects user-initiated transactions: SaveChanges
inside a BeginTransactionAsync block triggers OnFirstExecution which throws
InvalidOperationException. Fix: CreateExecutionStrategy().ExecuteAsync wraps the
entire tx block; mutable state (counters, contactByNorm, change tracker) reset at
lambda top for idempotent retry. Logic extracted to RunLoopAsync local function
shared by dry-run and execute paths.
Regression test (Test 7): FakeRetryingStrategy with MaxRetryCount=1 reproduces
the OnFirstExecution check in CI without a live Npgsql instance.
165/165 tests, ef has-pending=No, no schema change.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>