


Modificar una biblioteca de contratos inteligentes sin romper los proyectos que la usan
Úsalo cuando una IA edita una biblioteca de contratos inteligentes que heredan otros proyectos. Cambia el archivo dueño del comportamiento, sigue el linter, mantiene funciones, eventos y disposición del almacenamiento, y revisa a mano código de riesgo como criptografía y actualizaciones.
Para usar estas reglas de IA
## Diseñar para los proyectos que heredan la biblioteca y acordar los cambios antes en un issue
- Este repositorio es una biblioteca de contratos inteligentes: contratos abstractos y bibliotecas reutilizables pensados para ser heredados y extendidos por proyectos derivados, no una aplicación desplegada. La mayoría de las convenciones existen porque el código sirve de base para otros.
- Como los proyectos que heredan dependen de ella, hay que diseñar pensando en la extensión: las funciones deben poder sobrescribirse donde se espera extensión, los tipos de argumentos no deben restringir en exceso a quienes heredan, y la API pública no debe imponer un contexto de llamada particular a los contratos hijos.
- Lee primero la guía oficial para colaboradores humanos del repositorio; es la fuente de verdad. Una guía para asistentes de IA solo cubre lo específico del trabajo asistido y las convenciones que no están documentadas en otro lugar. Si ambas discrepan, prevalece la especificación humana.
- Discute cualquier cambio no trivial en un issue antes de abrir un pull request. Consigue primero un acuerdo sobre la dirección en lugar de implementar sin que te lo pidan, y luego abre el PR con ese alcance ya acordado.
## Cambiar el archivo dueño del comportamiento y no editar a mano archivos generados
- Un repositorio de biblioteca tiene varias superficies distintas: el código fuente de la biblioteca (la API pública), los mocks solo para pruebas que la reflejan, las definiciones de interfaz puras, los wrappers autogenerados, las especificaciones de verificación formal, las fuentes de documentación y los informes de auditoría históricos. Identifica qué superficie es dueña de un archivo antes de editarlo, y modifica la superficie que es dueña del comportamiento en lugar de una adyacente. Una sola tarea puede tocar varias superficies a la vez, así que no des por hecho que un cambio es "solo código" o "solo documentación" sin comprobarlo.
- Nunca edites a mano un archivo autogenerado o gestionado por herramientas. Un archivo generado de forma procedural a partir de una plantilla lleva un encabezado que lo indica: edita la plantilla y regenera el archivo en su lugar, porque la integración continua (CI) verifica que esté actualizado con una comprobación de diferencias de generación, y las ediciones manuales se sobrescriben. Los wrappers autogenerados normalmente están excluidos de git (gitignored) y se reconstruyen bajo demanda.
- Deja los metadatos mantenidos por herramientas en manos de esas herramientas. La línea de encabezado "última versión actualizada" de cada archivo la mantiene automáticamente, a partir del historial de control de versiones, la herramienta de publicación (release tooling); no la añadas ni la edites. Tu responsabilidad se limita a lo que esa herramienta no gestiona, como la línea del identificador de licencia.
## Dejar al linter las reglas de nombres y visibilidad, sin repetirlas en revisiones
- Un linter ya configurado impone las convenciones mecánicas sobre el código fuente de la biblioteca (los mocks y los tests suelen estar exentos): las variables de estado son `private` por defecto, con `constant` e `immutable` como únicas excepciones; el prefijo de guion bajo se corresponde con la visibilidad, así que el estado y las funciones `private` e `internal` llevan un guion bajo al principio mientras que los miembros `public` y `external` no; los nombres de interfaz llevan el prefijo `I`; los contratos y eventos usan CapWords; los parámetros y modificadores usan mixedCase; las bibliotecas solo exponen funciones `internal` o `private`.
- Si una regla del linter ya detecta un problema, no gastes tokens explicándolo en una revisión de código; corrígelo y sigue adelante. Repetir en un comentario de revisión una regla que ya impone el linter es ruido, no señal.
## Seguir las reglas de versión del compilador e imports que el linter no detecta
- Versión mínima del pragma del compilador: no elijas a mano la versión mínima. Ejecuta la herramienta de minimización de pragma del proyecto, que recorre el grafo de dependencias, compila contra cada versión candidata del compilador y escribe de vuelta la versión más baja que funciona para cada archivo (un prefijo `>=` para las interfaces, `^` para las implementaciones y bibliotecas). Subir esa versión mínima a la ligera puede introducir opcodes que no son compatibles en algunas cadenas objetivo, así que el resultado de la herramienta es la respuesta segura.
- Los imports deben ser 100% nominales, con llaves, y relativos dentro del árbol de código fuente. No se permiten imports con comodín.
- El orden de herencia debe ser globalmente consistente. Si cambias una lista `is A, B, C`, recompila y ejecuta la verificación del orden de herencia antes de hacer push.
- Entradas de changelog: todo cambio que altere el comportamiento de un contrato necesita una. Sáltatela solo en ediciones que sean únicamente de documentación, refactorizaciones internas sin efecto visible para el usuario, o tareas puramente internas del repositorio.
## No cambiar las funciones ni la disposición del almacenamiento existentes y añadir pocas dependencias
- Los contratos publicados se heredan en proyectos derivados y a menudo se transpilan a una variante actualizable independiente. No cambies las firmas de las funciones `public` o `external` existentes, la forma de los eventos o errores existentes, ni la disposición de almacenamiento de los contratos existentes. Haz que los cambios sean aditivos; marca como obsoleto en lugar de eliminar. Un cambio disruptivo (breaking change) es una decisión del mantenedor ligada a una versión mayor, nunca algo que se introduzca durante el trabajo rutinario.
- Mantén mínima la superficie de dependencias. Reutiliza las funciones auxiliares ya existentes en la biblioteca antes de buscar fuera de ella. No añadas un paquete de terceros ni un nuevo import externo sin la aprobación del mantenedor; el código que realmente necesita dependencias de terceros más pesadas pertenece a un repositorio aparte, de comunidad o de extensiones, no a la biblioteca principal.
## Revisar a mano el código de criptografía y de slots de almacenamiento, donde la IA suele fallar
- En estas áreas, las sugerencias de la IA suelen ser plausibles pero incorrectas. Lee el código circundante y vuelve a deducir la afirmación antes de aceptar cualquier cambio:
- Criptografía: hashing, ECDSA, separadores de dominio de datos tipados (EIP-712), esquemas de firma, y matemática de emparejamiento (pairing) o BLS.
- Derivaciones de slots de almacenamiento, como los slots con espacio de nombres (ERC-7201): recalcúlalos con la función auxiliar de derivación canónica y compáralos con la constante declarada. La fórmula del comentario en línea es obligatoria, no decorativa.
- Disposición de almacenamiento en contratos procesados por proxy o por el transpilador: añadir, eliminar o reordenar campos rompe los proxies ya desplegados. Revisa el diff de disposición de almacenamiento aunque la CI también lo ejecute.
- `delegatecall`, ensamblador en línea (inline assembly) y seguridad de memoria: verifica que cualquier anotación de memory-safe sea honesta y que el uso de la pila y del espacio de trabajo temporal esté acotado.
- Bloques `unchecked`: vuelve a deducir el argumento de que el desbordamiento es imposible para cada ruta de código. El comentario de justificación en línea es el contrato que debes respetar.
- Autorización de actualización: el hook de autorización de actualización está vacío en la base por diseño, así que cada sobrescritura debe restringir quién puede llamarlo.
- Constructores de implementación de proxy: confirma que los inicializadores estén deshabilitados (por ejemplo, con una llamada de deshabilitación de inicializadores) en los objetivos de implementación de proxy UUPS o transparente.
## Dejar en manos de personas los cambios de API pública y los juicios de seguridad
- Añadir o renombrar API pública, o decidir si una funcionalidad debe estar en la biblioteca: abre un issue y consigue primero la decisión de un mantenedor.
- Evaluaciones de seguridad y opiniones de auditoría: remite a auditores humanos en lugar de afirmar que un contrato es seguro.
- Nuevos estándares de interfaz sin una directriz explícita.
- Reestructurar tests sin un cambio correspondiente en el contrato.
- Nunca inventes recompensas de seguridad. No afirmes, insinúes ni inventes un programa de recompensas por errores (bug bounty), un monto de recompensa o criterios de elegibilidad. Haz referencia únicamente a un programa oficialmente documentado, si de verdad existe.
