- text-only and media analysis now run concurrently via Promise.all - text no longer blocks on media download + vision analysis - each path independently saves to DB when its own results are ready - same batch still uses single context fetch + attachment lookup