


Crear servicios Rust asíncronos que resistan cancelaciones y fallos
Para servicios Rust asíncronos: la IA termina el código real sin simulaciones, maneja errores y cancelaciones con seguridad, prueba a través de la interfaz real del servicio y pasa todas las comprobaciones antes de darlo por terminado.
Para usar estas reglas de IA
## Terminar el código real en lugar de usar simulaciones o stubs
Completa el comportamiento solicitado de principio a fin. No sustituyas la lógica de producción que falte por mocks, implementaciones de reserva, stubs ni atajos exclusivos para pruebas.
- Utiliza dependencias reales y la ruta de integración efectiva.
- No manipules las pruebas para ocultar una implementación defectuosa.
- Evita soluciones provisionales del entorno que eludan la preparación obligatoria.
- Registra explícitamente en el plan o la especificación resultante todo trabajo incompleto que no pueda evitarse.
- Nunca afirmes que una función funciona sin pruebas procedentes de la ruta que utilizarán los usuarios.
La ejecución autónoma significa completar la ruta rigurosa, no reducir la definición de terminado.
## Aplicar las mismas decisiones de diseño a todos los tipos de datos relacionados
Cuando un sistema gestione varias familias relacionadas de señales o datos, diseña un comportamiento compartido para todas ellas, aunque una sola familia sea la prioridad actual.
- Identifica la semántica común a la ingesta, el almacenamiento, la búsqueda, el análisis y la gestión del ciclo de vida.
- Mantén las optimizaciones específicas de cada familia detrás de límites explícitos.
- Comprueba que las decisiones compartidas no favorezcan por accidente a la primera familia implementada.
- Conserva un comportamiento coherente de errores, configuración y observabilidad en todas las rutas.
- Documenta las diferencias intencionales en lugar de permitir que las implementaciones diverjan.
La priorización puede controlar el orden de entrega, pero no debe reducir silenciosamente el alcance de la arquitectura.
## Poner la seguridad primero, luego la velocidad y después la comodidad
Aplica esta prioridad de ingeniería: primero la seguridad, después el rendimiento y, en tercer lugar, la comodidad del desarrollo. Optimiza únicamente después de entender las invariantes y el comportamiento ante fallos.
- Rechaza las entradas no válidas en los límites públicos.
- Define límites explícitos como constantes con nombre y devuelve errores estructurados cuando se superen.
- No ocultes un fallo de una dependencia, del almacenamiento o de la red mediante una alternativa que indique éxito.
- Trata un estado inesperado como un error o una invariante vulnerada, no como una operación que no hace nada y se considera correcta.
- Permite que falten datos opcionales únicamente cuando el contrato los defina explícitamente como opcionales.
El trabajo de rendimiento debe conservar la corrección durante los fallos, los reintentos, las cancelaciones y el avance parcial.
## Usar aserciones de depuración para reglas internas y errores para entradas no válidas
Utiliza aserciones activas solo durante la depuración para documentar las invariantes internas que quienes revisan puedan analizar. Usa resultados de error recuperables para entradas de usuario no válidas, datos externos y condiciones de ejecución, porque las aserciones de depuración pueden desaparecer en las compilaciones optimizadas.
- Propaga los errores de biblioteca con `Result` y el operador `?`.
- Evita los métodos de extracción incondicional en el código de biblioteca reutilizable.
- Conserva tipos de error significativos en lugar de aplanar todos los fallos.
- Utiliza operaciones del sistema de archivos y de metadatos que puedan fallar cuando sus errores aporten información.
- Añade contexto sin descartar la causa original.
- Nunca ignores silenciosamente un error mediante una asignación no utilizada.
Un estado imposible debe fallar de forma suficientemente visible para facilitar el diagnóstico.
## Mantener el código asíncrono seguro cuando se cancelan tareas
Supón que el trabajo asíncrono puede cancelarse en cualquier punto de suspensión. Estructura las transiciones de estado de forma que una cancelación no pueda exponer un estado parcialmente actualizado ni provocar la pérdida de datos.
- Prefiere la propiedad al estilo de actores y el paso de mensajes para el estado mutable sensible a las cancelaciones.
- No mantengas un bloqueo a través de un punto await.
- Utiliza secciones críticas síncronas cuando una mutación deba ser atómica.
- Cancela de forma cooperativa mediante una señal de cancelación, en vez de interrumpir tareas arbitrariamente.
- En los bucles de selección, ancla (pin) y reanuda el Future en curso en lugar de volver a crearlo y descartarlo.
- Haz que el cierre y la limpieza sean idempotentes.
Elige una clonación más sencilla o la propiedad compartida en el código de actores y asíncrono cuando ello haga más seguros la propiedad y el comportamiento ante cancelaciones.
## Mantener claros los tipos y la propiedad, y dividir los archivos grandes
Utiliza identificadores de dominio y alias de tipo establecidos, en lugar de pasar cadenas sin tipar para representar conceptos nuevos. Deja que el sistema de tipos distinga los valores que no deben mezclarse.
- Evita ocultar nombres dentro de una función cuando dificulte la comprensión de las transiciones de estado.
- Devuelve referencias cuando la propiedad siga siendo local y la clonación sea innecesaria.
- Utiliza propiedad compartida explícita cuando los valores atraviesen los límites de una tarea.
- Prefiere los bucles procedimentales cuando las cadenas de iteradores dificulten la lectura de un flujo de control que puede fallar.
- Divide los archivos y las funciones demasiado grandes según responsabilidades coherentes.
- Mantén las interfaces públicas separadas de los detalles de implementación.
La legibilidad es una herramienta de fiabilidad cuando el código coordina estados asíncronos.
## Probar a través de la interfaz real del servicio que usan las personas
No declares terminada una función hasta haberla ejercitado a través de la pila pública real. Si los usuarios acceden al comportamiento mediante un protocolo de red, una puerta de enlace o un límite de servicio, prueba a través de ese límite en lugar de llamar directamente a una función interna.
1. Inicia el servicio real con una configuración representativa.
2. Envía la entrada por la interfaz de ingesta o de comandos compatible.
3. Recupera el resultado por la interfaz de consulta o de respuesta compatible.
4. Verifica la persistencia, la correspondencia de errores y los efectos secundarios observables.
5. Confirma que el comportamiento interno y el público coincidan.
Las pruebas internas son útiles, pero no sustituyen la evidencia obtenida a través de la ruta de producción.
## Elegir el tipo de prueba según su objetivo, incluidas las pruebas de fallos
Utiliza pruebas unitarias rápidas para la lógica aislada, pruebas basadas en propiedades para espacios de estados amplios, pruebas de inyección de fallos para la resiliencia y pruebas de integración para el comportamiento completo del servicio.
- Acota las entradas de las pruebas de propiedades lo suficiente para obtener contraejemplos útiles.
- Utiliza fixtures de servicios reales cuando importe el comportamiento del almacenamiento o del protocolo.
- Limita los reintentos a los conjuntos de pruebas que toleren de forma intencional una planificación no determinista.
- Ejecuta la cobertura de puntos de fallo cuando los cambios afecten a la recuperación o a las transiciones de estado.
- Añade una prueba de integración para cada endpoint público nuevo.
- Prueba la ruta de error con la misma intención que la ruta correcta.
No permitas que los reintentos repetidos conviertan un defecto determinista en un aprobado aparente.
## Ejecutar las comprobaciones con la cadena de herramientas fijada y los comandos del repositorio
Ejecuta la compilación, el formato, los lints, las pruebas, las comprobaciones de documentación y licencias, las auditorías de dependencias y la revisión ortográfica mediante los comandos definidos por el repositorio.
- Utiliza la cadena de herramientas fijada y el canal de formateador requerido.
- Inicia los servicios locales declarados antes de los conjuntos de integración y detenlos al terminar.
- Transmite la configuración de prueba mediante las variables de entorno documentadas sin incrustar credenciales reales.
- Ejecuta primero el paquete afectado de alcance reducido y después el conjunto del espacio de trabajo con todas las características (features) habilitadas.
- Trata cada advertencia de lint como un trabajo que debe resolverse o justificarse con la excepción específica más pequeña posible.
- Comprueba que cada cambio se compile de forma independiente, no solo como parte de un cambio posterior apilado.
Los comandos directos solo son aceptables cuando conservan la preparación que realiza el flujo de trabajo oficial.
## Registrar los cambios de arquitectura en tres tipos de registros
Sigue los cambios de la arquitectura mediante tres registros complementarios:
- **características:** requisitos proactivos que debe satisfacer la arquitectura;
- **carencias:** limitaciones descubiertas mediante incidentes, pruebas o el comportamiento en producción;
- **desviaciones:** apartamientos intencionales de la arquitectura preferida, incluidos sus motivos y restricciones.
Vincula los cambios de código con el registro pertinente cuando alteren las garantías del sistema. Mantén separados los modelos formales, los flujos de simulación, los registros de decisiones y el estado de implementación para que un diseño aspiracional no se confunda con un comportamiento terminado.
Actualiza el registro cuando las evidencias cambien la arquitectura, no solo cuando se anuncie una función nueva.
## Responder a los comentarios de revisión en su propio hilo
Facilita la revisión de los cambios manteniendo las diferencias enfocadas y las explicaciones unidas a la decisión que abordan.
- Responde a un comentario de revisión en su hilo existente, en lugar de crear otro comentario en la misma ubicación.
- Verifica mediante la interfaz de alojamiento que la respuesta esté vinculada al comentario principal previsto.
- Explica por qué es necesaria una invariante, excepción permitida, clonación o desviación que no resulte evidente.
- Separa las refactorizaciones no relacionadas de los cambios funcionales.
- Actualiza las directrices evolutivas cuando un patrón de fallo repetido revele una regla duradera.
Una revisión ordenada conserva el contexto y evita que el mismo problema se resuelva en conversaciones paralelas.
## Pasar todas las comprobaciones del diff final antes de dar el trabajo por terminado
Antes de informar que el trabajo está terminado, examina la diferencia final y confirma:
- que todos los lints aplicables pasen sin advertencias sin explicar;
- que las comprobaciones de formato pasen para cada archivo fuente y de prueba modificado;
- que no quede ninguna extracción incondicional, supresión silenciosa de errores ni clonación injustificada;
- que pasen las pruebas de las interfaces de producción y las pruebas de integración afectadas;
- que pasen los encabezados obligatorios, las convenciones de registro, la documentación y las auditorías de dependencias;
- que los archivos y funciones nuevos conserven un alcance enfocado y sean mantenibles;
- que no haya credenciales ni valores sensibles.
Corrige los fallos desde su causa. No desactives comprobaciones, debilites pruebas ni eludas la ruta de producción para obtener un resultado aprobado.
