Buscar/Haz cambios pequeños y compatibles en un proyecto Java dividido en módulos

Haz cambios pequeños y compatibles en un proyecto Java dividido en módulos

Para que una IA modifique un proyecto Java dividido en módulos. Revisa primero las reglas de compilación y CI, mantiene funcionando las versiones antiguas de Java y las dependencias entre módulos, prueba en el nivel adecuado y pregunta antes de cambios amplios o riesgosos.

Para usar estas reglas de IA
## Revisa las reglas de compilación, formato y CI antes de editar Trata las directrices del repositorio, la configuración de compilación, las reglas de formato y las comprobaciones de integración continua como contratos ejecutables. Lee las instrucciones aplicables antes de editar e identifica qué reglas se aplican mecánicamente. - Localiza el wrapper oficial de compilación, el formateador, las comprobaciones estáticas, los comandos de prueba y la política de contribución. - Antes de cambiar código, rastrea el módulo responsable y sus dependencias. - Prefiere las utilidades y los patrones establecidos del proyecto a las alternativas que solo resulten prácticas en el entorno local. - Distingue entre compatibilidad del código fuente, requisitos de las herramientas de compilación, compatibilidad con el entorno de ejecución y comportamiento de la distribución. - No desactives una barrera de calidad únicamente para conseguir que un cambio pase. Utiliza la entrada canónica más pequeña que controle el comportamiento solicitado. ## Mantén el código compatible con la versión de Java y las dependencias declaradas Una compilación puede requerir una cadena de herramientas más reciente aunque su código fuente siga siendo compatible con un entorno de ejecución anterior. Compila y prueba con el nivel de código fuente declarado; no supongas que un entorno local más reciente permite usar características nuevas del lenguaje o API nuevas de las bibliotecas. - Sustituye las API auxiliares no compatibles por equivalentes compatibles. - Cuando sea necesario, utiliza los espacios de nombres de dependencias reubicados o sombreados del repositorio. - Prefiere las utilidades del propio proyecto para la validación, la serialización, las colecciones, los archivos, los Future y el tiempo. - Evita las importaciones directas de terceros cuando la distribución aísle esas bibliotecas. - Antes de añadir una dependencia, analiza la compatibilidad, la licencia, el empaquetado y el impacto transitivo. Verifica la compatibilidad mediante el objetivo de compilación designado por el repositorio, no solo con una compilación local. ## Usa fábricas, builders y resultados inmutables en las API públicas Marca las API según la estabilidad prevista: los contratos públicos estables, los contratos públicos en evolución y las superficies de implementación internas deben permanecer diferenciados. - Haz que las fábricas devuelvan interfaces y oculta la construcción tras constructores privados o métodos de creación estáticos. - Usa builders para la configuración de varios pasos, con métodos fluidos y un único punto de construcción validado. - Mantén inmutables los objetos de resultado, con el estado declarado final, sin setters y con implementaciones completas de igualdad, hash y representación textual. - Proporciona interfaces genéricas y tipadas cuando quienes las llaman necesiten ambas formas sin conversiones inseguras. - Documenta los requisitos de seguridad entre hilos en los tipos públicos. Cambiar un contrato público exige un análisis de compatibilidad y la vía de versionado adecuada. ## Mantén las dependencias entre módulos en una sola dirección Traza el grafo de módulos antes de implementar. Los módulos fundamentales deben albergar los tipos y las interfaces compartidos; las capas de protocolo o transporte se construyen sobre ellos; los módulos pares de cliente y servidor no deben depender entre sí; las integraciones deben situarse por encima de las capas inferiores estables. - Define las interfaces compartidas en el módulo apropiado de nivel más bajo y coloca las implementaciones por encima. - Impide que los conectores y las integraciones opcionales filtren dependencias al núcleo. - Evita las dependencias circulares y las importaciones entre módulos pares motivadas únicamente por la comodidad. - Reproduce en las pruebas la estructura de paquetes del código de producción. - Sitúa el código generado, los recursos de distribución, los generadores de documentación y las utilidades de prueba en sus módulos designados. Cuando una función cruce límites, modifica explícitamente cada capa responsable en lugar de eludir la arquitectura. ## Distingue los tipos de error y protege el estado compartido con bloqueos Valida las entradas en los límites de la API con las utilidades de precondiciones estándar del proyecto y con mensajes que indiquen cómo actuar. Conserva la jerarquía de excepciones para que quienes llaman puedan distinguir los errores de usuario, los fallos reintentables y los fallos internos no comprobados. - Propaga los fallos asíncronos mediante las utilidades de Future y los manejadores de errores establecidos. - Compón el trabajo asíncrono en lugar de bloquearlo sin una razón documentada. - Protege el estado mutable compartido con bloqueos explícitos y documenta los campos protegidos. - Utiliza primitivas de visibilidad solo cuando el acceso fuera del bloqueo las requiera. - Cierra los recursos mediante una gestión estructurada de recursos. - Haz que las operaciones de cierre sean idempotentes cuando la limpieza pueda repetirse. No ocultes los fallos comprobados ni agrupes los errores reintentables y permanentes en una única excepción indiferenciada. ## Mantén compatibles las claves de configuración y los esquemas de mensajes Cuando corresponda, define la configuración mediante builders tipados con valores predeterminados, descripciones, valores opcionales y gestión de claves obsoletas. Utiliza claves jerárquicas y coherentes, y accede a los valores mediante la abstracción de configuración del repositorio. Para la serialización y los mensajes remotos: - conserva el esquema y la versión del protocolo declarados; - utiliza únicamente las formas de campo admitidas por esa versión; - vuelve a generar el código con el generador oficial después de cambiar el esquema; - mantén inmutables los mensajes de protocolo y marca debidamente los tipos internos de transporte; - representa explícitamente los campos opcionales; - nunca edites archivos generados cuando sean responsabilidad de un flujo de generación. Actualiza las pruebas de compatibilidad y la documentación generada cada vez que cambie un contrato de configuración o de comunicación. ## Escribe pruebas unitarias y de integración con las herramientas del proyecto Utiliza el marco de pruebas, la biblioteca de aserciones, las convenciones de nombres, las extensiones y los fixtures base elegidos por el repositorio. No incorpores aserciones alternativas ni mecanismos de tiempo de espera que entren en conflicto con la infraestructura general de pruebas. - Escribe pruebas unitarias específicas para el comportamiento local y pruebas de integración para los contratos entre componentes. - Utiliza nombres descriptivos que indiquen el comportamiento sometido a prueba. - Comprueba tanto los resultados correctos como los fallos esperados. - Reutiliza los fixtures de clúster, almacenamiento o servicio compatibles en lugar de crear una infraestructura paralela. - Ejecuta primero la prueba afectada más específica y después el conjunto directamente afectado. - Confirma que la prueba falla por el motivo previsto antes de usarla como demostración de una corrección. Realiza las pruebas a través del comportamiento público cuando un detalle interno de implementación no forme parte del contrato. ## Compila y verifica con el wrapper de compilación del proyecto Utiliza el wrapper del repositorio para la compilación, el formato, el análisis estático, las comprobaciones de licencias, la generación de código y las pruebas. Los comandos oficiales pueden preparar recursos generados o imponer requisitos de compatibilidad que una invocación directa de las herramientas pasaría por alto. - Compila con la cadena de herramientas documentada y conserva el objetivo de código fuente declarado. - Inicia las dependencias y los componentes de los servicios locales en el orden documentado. - Edita únicamente los archivos y valores de configuración compatibles. - Ejecuta el formateo antes de las comprobaciones estáticas. - Ejecuta los conjuntos afectados antes de una verificación más amplia. - Utiliza el perfil de cobertura cuando el cambio pueda alterar el comportamiento sometido a prueba. Comprende las etapas de integración continua y reproduce localmente la etapa pertinente antes de informar que el trabajo está terminado. ## Sigue el formateador y no mezcles cambios no relacionados en el diff Respeta el orden obligatorio de las importaciones y los modificadores, la sintaxis de matrices, las reglas de llaves, la política de espacios en blanco y las convenciones de nombres. Deja que el formateador oficial resuelva el estilo mecánico. - Evita las importaciones con comodines y los marcadores de comentarios o etiquetas de atribución prohibidos por el repositorio. - Mantén documentadas las API public y protected cuando el proyecto lo exija. - Respeta los límites de tamaño de archivo extrayendo responsabilidades coherentes, no comprimiendo el código a costa de la legibilidad. - Actualiza la documentación cuando cambien los comandos, la configuración, la compatibilidad o el comportamiento público. - Revisa la diferencia final para detectar reescrituras ajenas al cambio, ediciones accidentales de archivos generados, secretos y limpieza incompleta. No combines un cambio de comportamiento bien delimitado con una refactorización sin relación. ## Publica los cambios en ramas de revisión, nunca con force-push Trabaja en una rama autorizada y verifica cada repositorio remoto antes de hacer push. Mantén protegidas las ramas ascendentes o compartidas; publica los cambios mediante la vía de revisión del proyecto en vez de escribir directamente en objetivos protegidos. - Haz rebase o actualiza desde la rama base oficial mediante el flujo documentado. - Escribe un asunto de commit conciso y limitado al componente, y explica la motivación en el cuerpo cuando sea necesario. - Revisa la diferencia completa de la rama antes de publicarla. - Ejecuta el formateo, las comprobaciones estáticas y de licencias, y las pruebas afectadas. - Incluye un resumen sencillo y un plan de pruebas en la solicitud de revisión. - Identifica los cambios realizados con asistencia para que una persona los revise cuando lo exija la política de contribución. Nunca hagas force-push en una rama compartida ni utilices operaciones destructivas sobre el historial sin autorización explícita. ## Pregunta antes de trabajos amplios o destructivos, como nuevas dependencias o resets Avanza de forma autónoma con lecturas acotadas, compilaciones locales, pruebas, formato, diagnósticos y correcciones que sigan las reglas existentes. Pide permiso antes de realizar trabajos amplios o trascendentes, como refactorizaciones entre módulos, dependencias nuevas, migraciones de esquema, cambios en el sistema de compilación, cambios en la integración continua u operaciones destructivas. Sin permiso explícito, nunca: - incluyas credenciales o valores sensibles en un commit; - hagas push directamente a un objetivo ascendente protegido; - hagas force-push sobre el historial compartido ni elimines ramas; - ejecutes hard reset o una limpieza destructiva; - eludas hooks, comprobaciones estáticas o reglas de formato; - modifiques los resultados generados en lugar de su origen; - debilites las barreras de calidad para obtener un resultado satisfactorio. Antes de terminar, verifica las pruebas, el formato, las comprobaciones estáticas, los encabezados requeridos y la diferencia completa prevista. Si el alcance o la reversibilidad no están claros, detente y explica qué decisión hace falta.