Documentación · Conceptos

Mutantes equivalentes

Qué hacer con un wekufe que ningún test puede matar: el archivo .kalku/equivalent y por qué un agente solo puede proponer.

Decidir si dos programas son equivalentes es indecidible en general, así que ninguna herramienta encuentra todos los wekufe equivalentes. kalku evita generar los predecibles y hace que declarar el resto sea honesto y durable.

Tres tipos de sobreviviente

TipoEjemploQué se hace
Equivalentei >= 0 → i > 0 donde i nunca es 0 en ese puntoSe declara, con una razón
Inobservable por diseñoQuitar Logger.debug/1, :telemetry.execute/3 o un caché que existe solo por velocidadSe excluye por configuración (exclude_calls), nunca entrada por entrada
Difícil de matar, pero realUn caso de borde que ningún test ejercitaEs un hoyo: escribe el test, no lo suprimas

Dejar las llamadas inobservables fuera del archivo de equivalentes lo mantiene lo bastante pequeño para auditarlo.

El archivo .kalku/equivalent

Los equivalentes se declaran en .kalku/equivalent, que se versiona con el proyecto. Las entradas se identifican por significado y no por número de línea, así que sobreviven a ediciones en otra parte del archivo:

lib/my_app/parser.ex  MyApp.Parser.next_token/2  compare  ">="  #1   # index is always even here; > and >= agree

Los campos son: el archivo, la función que contiene el site, el spell, el texto original (como string JSON), el ordinal de ese texto dentro de la función, y la razón después de #.

  • Una entrada sin razón es un error.
  • Una entrada que no calza con ningún site es un error: una entrada huérfana no suprime nada o, peor, terminaría suprimiendo un wekufe distinto del que se justificó. La corrida no mide y sale con código 2.
  • El archivo suprime; no excusa. Un wekufe que sobrevive porque falta un test va en un test, no aquí.

Proponer, aceptar, rechazar

Un argumento de equivalencia no se puede verificar; un test que mata, sí. Por eso lo primero se queda como propuesta hasta que una persona lo lee.

kalku propose-equivalent <wekufe> --reason "index is always even here"
kalku accept <wekufe>
kalku reject <wekufe>

propose-equivalent agrega la propuesta a .kalku/equivalent.proposed, que kalku lee pero nunca aplica. accept la pasa a .kalku/equivalent; reject la rechaza, y el wekufe vuelve a pedir un test.

Una persona responde una propuesta a la vez, y la nombra. A propósito, no hay forma de aceptarlas todas juntas: el sentido de que un agente proponga y una persona acepte es que alguien leyó cada supresión.

Las supresiones hacen ruido

Las supresiones que agrega un pull request, sean entradas nuevas en .kalku/equivalent o un exclude o exclude_calls más amplio, aparecen bajo su propio encabezado en cada reporte. Esconder un hoyo tiene que ser tan visible como dejarlo.