


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.
