Red-team correctness findings:
- SqliteDb.transaction now serializes top-level transactions with an async
mutex and tracks re-entrancy via AsyncLocalStorage (nested calls -> savepoints,
no deadlock). The old shared txnDepth counter let concurrent async callers
interleave BEGIN/COMMIT on the one connection -> silent data loss; a 50-way
concurrent read-modify-write test now lands exactly.
- generateRecurring wraps each plan in try/catch: one misconfigured plan is
parked (audited 'generate_failed') and the scan continues, instead of aborting
all remaining generation and the entire auto-send drain, every scan.
- POST /modules/:id/notify broadcast IIFE gets a trailing catch so a mid-loop
throw answers the request instead of hanging it.
Full suite 388 green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>