


Añadir funciones a una biblioteca multilenguaje de infraestructura como código sin romper a los usuarios actuales
Úsalo al cambiar una biblioteca tipada de IaC que genera enlaces para otros lenguajes. Pone cada función en la capa adecuada, evita sintaxis que los enlaces no admiten, protege los cambios con indicadores de funciones, limita los permisos y añade documentación y pruebas.
Para usar estas reglas de IA
## Mantener funcionando el código de los usuarios y exponer toda la plataforma
Trabaja para los usuarios, responsables y el ecosistema amplio de la biblioteca, no solo para quien solicita el cambio.
- Conserva la retrocompatibilidad; el código existente y la infraestructura sintetizada deben seguir funcionando de forma predeterminada.
- Sigue el principio de mínima sorpresa: las API deben coincidir con el modelo mental del usuario.
- Expón toda la superficie de capacidades de la plataforma y ofrece valores predeterminados razonables que puedan sobrescribirse.
- Conserva una vía de acceso al recurso generado de bajo nivel para que la falta de funciones de alto nivel nunca bloquee al usuario.
- Si las reglas son ambiguas, registra la decisión y su razonamiento en la descripción del cambio en vez de adivinar silenciosamente.
Si el trabajo solicitado queda fuera de la creación o revisión de código para este tipo de biblioteca, detente y señala la discrepancia de alcance. No apliques reglas especializadas a trabajos sin relación.
## Poner la mayoría de las funciones en la API escrita a mano de nivel 2
Mantén tres niveles de abstracción distintos:
- El nivel 1 contiene envoltorios generados a partir del esquema de recursos del proveedor. Nunca los edites manualmente.
- El nivel 2 contiene API manuscritas, basadas en la intención y con valores predeterminados útiles. La mayoría de las funciones pertenecen aquí.
- El nivel 3 contiene patrones de varios recursos. Añade patrones nuevos solo cuando el repositorio acepte expresamente ese nivel de abstracción.
Diseña el nivel 2 en torno a la intención del usuario y no al esquema sin procesar del proveedor. Oculta a los consumidores ordinarios los detalles del esquema generado, el cableado interno, las acciones de permisos y los identificadores físicos, pero sigue ofreciendo todas las capacidades del proveedor.
Representa los contratos de recursos como interfaces para que implementaciones de terceros funcionen como las propias. Prefiere la interfaz mínima que satisfaga un parámetro: primero una referencia que solo contenga el identificador, una interfaz de comportamiento completa solo cuando hagan falta operaciones prácticas y clases concretas únicamente en casos excepcionales.
## Decidir si cada función nueva va en un mixin, una fachada o un trait
Ubica cada función según aquello a lo que afecta:
1. El paso directo de una propiedad de bajo nivel sin lógica pertenece a un mixin de propiedades ligero.
2. La lógica que cambia las propiedades o el ciclo de vida del propio recurso pertenece a un mixin independiente.
3. El comportamiento que sirve a consumidores externos, como concesiones, métricas o eventos, pertenece a una fachada.
4. Una capacidad transversal que consultan otras construcciones pertenece a un rasgo.
5. En los demás casos, usa un método de la construcción de nivel 2.
No confundas estas funciones. Los mixins miran hacia dentro, las fachadas hacia fuera y los rasgos anuncian capacidades independientes del servicio.
Usa guardas de tipos estáticas basadas en marcadores estables de ejecución en vez de `instanceof`, porque los objetos pueden cruzar límites de paquetes o lenguajes. Conserva bases abstractas para la implementación, pero no las aceptes como parámetros públicos.
## Nombrar la API pública con coherencia y evitar tipos que otros lenguajes no admiten
Usa nombres públicos coherentes: PascalCase para clases y enumeraciones, camelCase para propiedades y métodos, prefijo `I` para interfaces de comportamiento, ningún prefijo para estructuras de datos y mayúsculas con guiones bajos para miembros de enumeración. Conserva la terminología oficial de la plataforma e incluye unidades cuando no exista un tipo fuerte.
Los objetos de propiedades deben ser de solo lectura, planos y llevar el nombre de la construcción. Toda propiedad opcional necesita un valor predeterminado documentado que explique el comportamiento, no que solo diga que está indefinida. Prefiere tipos fuertes de duración, tamaño y referencia de recurso frente a números o identificadores sin tipo.
No expongas tipos generados de bajo nivel mediante propiedades de alto nivel. Evita tipos unión y otras construcciones no compatibles con el generador de enlaces; usa en su lugar clases similares a enumeraciones, objetos de propiedades separados o métodos de fábrica.
La ubicación de los archivos de tipos públicos forma parte del contrato externo. No los muevas sin una razón sólida. Evita tipos mapeados o condicionales, funciones sobrecargadas, espacios de nombres específicos de un lenguaje y constantes de objeto exportadas cuando no puedan representarse de modo coherente en los lenguajes de destino.
No uses métodos fluidos que devuelvan `this`; se traducen mal entre lenguajes y ocultan mutaciones detrás del encadenamiento.
## Escribir errores de validación claros y comprobar antes los valores sin resolver
Usa errores de validación con alcance cuando exista un contexto de construcción y sin alcance en los demás casos. Los códigos de error deben ser literales de compilación, reutilizables cuando coincidan la causa y la solución; los mensajes deben identificar el valor incorrecto, los valores esperados y la corrección requerida.
Prefiere corregir automáticamente una configuración segura antes que lanzar una excepción. Falla pronto ante un uso incorrecto de la API, adjunta validación posterior a la construcción para el estado acumulado y emite diagnósticos de síntesis para problemas ambientales. No captures errores irrecuperables de construcción; representa los resultados verdaderamente recuperables en los valores de retorno.
Los valores sin resolver pueden representar cadenas, números, listas o atributos de recursos. Comprueba si un valor está sin resolver antes de validar longitud, intervalo, iteración o valor lógico. Las listas tokenizadas pueden exponer longitudes de marcador y los valores escalares tokenizados pueden aparentar ser falsos.
Usa comprobaciones explícitas de indefinición para valores opcionales, una conversión numérica consciente de tokens y nunca incluyas atributos de recursos sin resolver en resúmenes para nombres físicos.
Para el estado acumulado tras la construcción, usa una caja de valores diferidos que capture los puntos de llamada de mutación. Usa cajas de lista, valor, mapa o conjunto; pásalas a propiedades de bajo nivel mediante adaptadores de tokens; modifícalas mediante operaciones de la caja; y nunca cambies el árbol de construcciones dentro de una llamada diferida o de caja.
## Limitar los permisos y proteger los cambios de comportamiento con indicadores de funciones
Prefiere acciones de permisos concretas frente a comodines de servicio completo, limita los identificadores de recursos al prefijo práctico más estrecho y agrupa las acciones relacionadas por alcance de recurso. Usa las funciones auxiliares de concesión de la biblioteca en vez de ensamblar manualmente declaraciones de políticas.
Las políticas de confianza deben incluir condiciones de cuenta y recurso de origen cuando exista riesgo de agente delegado confuso. Las concesiones de cifrado deben limitar el uso al servicio previsto. Emite una advertencia durante la síntesis siempre que la configuración produzca acceso público.
Cuando cambie el comportamiento observable de una API existente, protege la compatibilidad con un indicador de función:
- Usa un indicador de corrección cuando el comportamiento anterior fuera incorrecto.
- Usa un indicador de valor predeterminado de API cuando el comportamiento anterior siga siendo válido pero ya no se recomiende, y documenta la compatibilidad con el comportamiento antiguo.
- Haz que las aplicaciones no configuradas conserven su comportamiento anterior.
- Los indicadores de seguridad pueden reducir la confianza o los permisos, pero no deben ampliarlos silenciosamente; un acceso más amplio exige una opción explícita de API.
No uses un indicador solo porque exista una construcción de reemplazo. Marca como obsoleta la construcción anterior y advierte de los cambios de comportamiento mediante el mecanismo estándar de anotaciones.
## Compilar primero el paquete afectado y actualizar las instantáneas de integración
Compila el paquete afectado antes de ejecutar pruebas, análisis, instantáneas de integración o comprobaciones de ejemplos de documentación. Durante la iteración, usa el módulo o destino de prueba pertinente más estrecho; antes de la entrega, vuelve a los controles de paquete y compatibilidad exigidos por el repositorio.
Conoce qué archivos son generados, dónde residen las pruebas de integración estables y experimentales y dónde las referencias de diseño para agentes prevalecen sobre guías más largas para personas. Nunca edites directamente fuentes generadas de nivel 1.
Usa los comandos de paquetes y directorios de trabajo del repositorio en vez de inventar rutas alternativas de compilación. Ejecuta correcciones automáticas de análisis solo cuando la diferencia resultante permanezca dentro del alcance solicitado.
Al cambiar identificadores lógicos, actualiza todas las instantáneas de integración afectadas, incluidas las de otros paquetes. El éxito de una prueba unitaria local no demuestra que los enlaces generados, los ejemplos de documentación ni las plantillas de integración sigan compilando.
## Documentar toda API pública nueva y mantener los ejemplos compilables
Documenta cada clase, método, propiedad e interfaz pública nueva. Usa un resumen breve, después una línea en blanco y un cuerpo explicativo. Incluye etiquetas de parámetros, retorno, valor predeterminado, referencia relacionada, ejemplo y atributo generado cuando correspondan.
Los nombres de atributos deben comenzar por el tipo de recurso, no por nombres ambiguos. Copia las descripciones oficiales de la plataforma cuando existan, pero no dupliques documentación en redefiniciones que la heredan de una interfaz base.
Cada guía de módulo debe indicar su madurez, colocar un ejemplo sencillo cerca del principio e incluir ejemplos para los casos de uso principales. Todos los ejemplos tipados ordinarios deben compilar; usa el marcador explícito de exclusión del repositorio solo cuando una prueba realmente no pueda aplicarse.
Cada cambio de función debe actualizar la guía del módulo pertinente. El texto de documentación por sí solo no sustituye las pruebas de API, y una implementación de API no justifica ejemplos obsoletos.
## Comprobar propiedades concretas en pruebas unitarias y añadir pruebas de integración
En las pruebas unitarias, comprueba las propiedades generadas concretas que importan en vez de comparar plantillas completas o aceptar valores arbitrarios. Usa deliberadamente comparadores de objeto parcial, objeto exacto, matriz, expresión regular y ausencia.
Cubre los valores límite con pruebas basadas en datos. Las pruebas de error deben comprobar el diagnóstico exacto e identificar el comportamiento de fallo en el nombre de la prueba. Prueba las funciones auxiliares por separado de las construcciones y conserva las pruebas de API obsoletas.
Las propiedades opcionales nuevas necesitan pruebas de retrocompatibilidad que demuestren que el comportamiento predeterminado no cambia. Las funciones auxiliares de concesión deben probarse con roles, usuarios y principales de servicio creados e importados.
Las pruebas de integración deben usar la construcción de pruebas de integración del repositorio sin una llamada adicional de síntesis. Se prefieren aserciones en todas las pruebas nuevas y son obligatorias para recursos personalizados. Evita pares de red abiertos salvo que el acceso abierto sea el comportamiento bajo prueba.
Añade cobertura de integración para tipos o propiedades de recursos generados nuevos, comportamiento entre servicios, versiones nuevas y recursos personalizados. Separa las pruebas por área funcional y mantén coherentes las extensiones y ubicaciones de las instantáneas.
## Escribir títulos de cambio con su issue y no cambiar nunca los identificadores estables
Usa títulos de cambio convencionales con el módulo afectado cuando corresponda. Los cambios de función y corrección deben referenciar una incidencia. Los cambios de función requieren pruebas unitarias, instantáneas de integración y actualización de la documentación del módulo.
Los cambios incompatibles solo pertenecen a paquetes expresamente experimentales y deben declararse de forma destacada en la descripción. Mantén un asunto por cambio; envía las modificaciones cosméticas por separado.
Nunca añadas abstracciones especulativas, cambies identificadores estables de construcciones, dejes código comentado o muerto ni silencies reglas de análisis para ocultar infracciones. Los cambios de identificador pueden reemplazar recursos desplegados y provocar pérdida de datos.
Antes de añadir validación a una API existente, determina si una entrada antes aceptada podía desplegarse correctamente. Si podía, protege el nuevo rechazo con un indicador de compatibilidad. Si siempre fallaba durante el despliegue, prefiere un fallo temprano de síntesis y documenta por qué se justifica la validación más estricta.
Antes de la entrega, revisa la diferencia para detectar ediciones de archivos generados, movimientos de tipos públicos, sintaxis incompatible con enlaces, instantáneas obsoletas, documentación ausente, regresiones de compatibilidad y cambios no relacionados.
