Cómo funciona
Sin monkey-patching, sin proxies en runtime: solo el timing correcto y metadata de Reflect.
El pipeline
DocfyModule.forRoot() se ejecuta de forma síncrona durante la fase de NestFactory.create(), antes de que se llame a SwaggerModule.createDocument(). Usa require() para cargar cada docs file companion, que ejecuta docs() y escribe metadata de Reflect directamente en los métodos del controller, exactamente como haría la sintaxis de decorators de TypeScript en tiempo de definición de clase.
Para cuando SwaggerModule.createDocument() escanea buscando metadata, todo ya está en su sitio. Sin monkey-patching, sin proxies en runtime.
Timing
onModuleInit y otros lifecycle hooks se disparan después de que SwaggerModule.createDocument() ya se haya llamado en main.ts. Cualquier enfoque basado en onModuleInit produciría documentación Swagger vacía. Por eso nestjs-docfy evita ese camino y usa un require() síncrono dentro de forRoot(), que se ejecuta durante NestFactory.create(), antes de cualquier lifecycle hook o llamada a SwaggerModule.
CLI: análisis estático
El CLI generate usa ts-morph para análisis estático: lee el AST de TypeScript sin ejecutar código del proyecto. Todas las rutas y patrones glob dados por el usuario se validan y sanitizan antes de usarse.