Resumen

  • El signo $ de SEARCHRES representa el contenido actual de una variable del servidor. No lleva incrustado si nació de SEARCH o UID SEARCH; FETCH o UID FETCH determina si se usa como secuencias o como UID.
  • Para demostrar qué población recibió una acción, hay que conservar el buzón seleccionado, UIDVALIDITY, el productor SAVE, el consumidor, el orden, los expunges y el resultado observado. El símbolo aislado no prueba identidad.

El migrador había localizado todos los mensajes anteriores a una fecha mediante UID SEARCH. Su siguiente paso usó FETCH sin el prefijo UID. En la revisión, alguien sostuvo que aquello era incoherente: «si la búsqueda devolvió UID, el conjunto guardado debe seguir siendo UID». RFC 5182 dice otra cosa. $ puede cruzar esa frontera y el servidor lo interpreta según el comando que lo recibe.

No se trata de una conversión accidental. Es parte explícita del diseño. También puede ocurrir a la inversa: SEARCH ordinario alimenta UID FETCH. El atajo transporta pertenencia; el contexto posterior elige el espacio de numeración. Si el registro guarda solo «se reutilizó el último resultado», ha perdido el dato que permite reconstruir la operación.

El ejemplo es hipotético y no atribuye un fallo a ningún producto. Sirve para separar tres capas que una interfaz suele unir: criterios de búsqueda, conjunto interno y efecto del comando siguiente.

El servidor evita un viaje de ida y vuelta

Sin SEARCHRES, el servidor envía una lista, el cliente la analiza, la convierte en un message-set y la devuelve para FETCH, STORE, COPY, otra SEARCH o UID EXPUNGE. RFC 5182 permite pedir RETURN (SAVE): el servidor conserva el resultado y el cliente coloca $ donde iría la lista.

Un servidor que anuncia SEARCHRES también implementa ESEARCH. Si SAVE aparece sin otra opción de retorno, incluso se suprime la respuesta SEARCH que habría mostrado los identificadores. El cliente puede encadenar trabajo sin conocer materialmente la lista. Ese es el ahorro: ancho de banda, latencia y formateo.

No es una base de datos de consultas. Solo hay una variable. No recibe un nombre duradero, no conserva por obligación el programa de búsqueda y no ofrece varias versiones. Una SAVE exitosa reemplaza lo anterior. Presentarla como «búsqueda guardada» en un control operativo confunde el mecanismo de transporte con un activo auditable.

La aplicación puede añadir su propia identidad: un job inmutable, la consulta exacta, alcance, autor, tiempo y población esperada. Pero esa identidad pertenece a la aplicación. El estándar no la entrega escondida dentro de $.

El tipo aparece cuando se consume

IMAP mantiene dos formas de señalar mensajes. Los números de secuencia dependen de la posición actual en el buzón seleccionado; los UID viven dentro de una generación marcada por UIDVALIDITY. SEARCHRES permite que un mismo conjunto conceptual sea consumido en ambos contextos.

Por eso, «la búsqueda fue UID» no basta para explicar un FETCH posterior. El auditor necesita la forma literal del consumidor. También necesita los eventos intermedios: un EXPUNGE elimina del conjunto el mensaje afectado y reajusta los números de secuencia restantes; un nuevo UIDVALIDITY vacía por completo la variable.

SELECT o EXAMINE exitosos también la dejan vacía. La selección de buzón no es una preferencia de pantalla, sino la frontera donde adquieren significado los números. Un cliente que cambia de buzón y conserva en su modelo mental el viejo $ está transportando autoridad que el servidor ya retiró.

La unidad mínima de evidencia es, por tanto, una época: conexión, buzón seleccionado, UIDVALIDITY, SAVE productor, opciones, orden recibido, mutaciones y consumidor. Solo ese conjunto permite responder qué mensajes pudo resolver el servidor en el momento de la acción.

Los fallos no conservan un respaldo invisible

RFC 5182 separa estados que un controlador genérico podría mezclar. Una búsqueda que termina BAD no altera la variable. Una búsqueda sin SAVE tampoco, tanto si tiene éxito como si devuelve NO. Pero si una búsqueda con SAVE devuelve NO, la variable se vacía.

La razón operativa es contundente. Si el intento de instalar un conjunto nuevo falla, conservar el antiguo detrás del mismo signo permitiría que una acción posterior operara sobre una población obsoleta. El estándar prefiere el vacío verificable.

El servidor también puede rechazar SAVE por límites de recursos. Debe responder NO con NOTSAVED y vaciar el conjunto. El documento reconoce que mantener estado adicional facilita presión de denegación de servicio y permite limitar los resultados guardados entre conexiones.

Una reintento correcto no ejecuta STORE o COPY sobre $ suponiendo que el conjunto anterior sobrevivió. Vuelve a establecer explícitamente la búsqueda y registra una nueva cadena. El OK de un consumidor posterior no puede reparar retrospectivamente el SAVE fallido.

Vacío no equivale a error

Una búsqueda puede no encontrar nada. La selección, UIDVALIDITY, un SAVE fallido o un NOTSAVED pueden vaciar la variable. Un EXPUNGE puede quitar su último integrante. Aun así, $ sigue siendo un message-set válido que no coincide con ningún mensaje.

RFC 5182 muestra COPY terminando con OK y sin copiar nada. FETCH puede hacer lo mismo sin respuestas FETCH. Desde el punto de vista del protocolo, no existe contradicción. La orden válida fue ejecutada sobre un conjunto vacío.

Desde el punto de vista de una migración o una política, el denominador sigue abierto. ¿Se pretendía mover cero mensajes? ¿La búsqueda realmente dio cero? ¿El conjunto se borró por un cambio de selección? ¿Se perdió por un error? ¿Los miembros desaparecieron por expunge? Un solo contador de comandos exitosos no distingue esas causas.

La verificación debe comparar población prevista, resultado calculado, valor guardado en el instante relevante, miembros restantes y efecto observado. La interfaz puede mostrar verde solo después de explicar las diferencias, no simplemente después del tagged OK.

El orden de recepción gobierna el pipeline

SAVE seguido de un consumidor de $ crea dependencia directa. El servidor respeta el orden recibido, aunque pueda optimizar internamente la ejecución. Esto permite enviar SEARCH y FETCH juntos sin esperar una ronda de red.

También se puede enviar un SAVE y varios consumidores no ambiguos. COPY y STORE apuntan al mismo resultado en la secuencia prevista. Pero dos SAVE no crean dos variables. El segundo reemplaza al primero. Los tags correlacionan respuestas; no convierten los resultados en objetos nombrados.

Para un motor asíncrono, el grafo debe estar explícito. Cada consumidor señala al productor vigente en su posición de la secuencia. La llegada de una respuesta, por sí sola, no define qué valor tenía el estado cuando se aceptó la dependencia.

CONTEXT, definido por RFC 5267, ofrece otra clase de mecanismo: contextos identificados por tags, actualizaciones y cancelación. Compararlo con SEARCHRES evita pedir al último resultado lo que correspondería a un contexto duradero o a un objeto propio de la aplicación.

MIN, MAX, PARTIAL y COUNT cambian la promesa

SAVE no siempre conserva todos los matches. Con ESEARCH, SAVE MIN guarda solo el mínimo; SAVE MAX, solo el máximo; ambos juntos, uno o dos extremos. ALL o COUNT obligan a guardar todos los encontrados, aunque un servidor pudiera calcular COUNT sin construir normalmente la lista.

RFC 9394 establece que SAVE con PARTIAL, sin ALL, guarda la ventana parcial y los extremos aplicables. RFC 9738 añade la regla de truncamiento por MESSAGELIMIT. Este artículo no vuelve a tratar la incompletitud por límite, ya cubierta por BTW; la frontera aquí es que las opciones forman parte de la identidad del resultado incluso cuando todo funcionó.

Un job que registra los criterios pero omite las opciones todavía no puede reconstruir la población. «Mensajes antiguos» puede significar todos, el primero, el último o una página. La semántica está en la línea ejecutada, no en el nombre humano de la tarea.

Aprobar una cadena, no un carácter

IANA registra SEARCHRES y RFC 9051 incorpora su comportamiento en IMAP4rev2. Eso demuestra un contrato común. No demuestra que un servidor específico tenga recursos disponibles, que un cliente preserve dependencias ni que una migración haya terminado.

Las operaciones sensibles necesitan un recibo local: identificador de intención, criterios y opciones exactos, buzón, UIDVALIDITY, productor y consumidores, orden, resets, expunges, espacio de numeración, recuento afectado y resultado visible. Con esa estructura, $ puede acelerar la ejecución sin cargar con la historia.

La pregunta de cierre no es «¿respondió OK?». Es «¿podemos demostrar qué mensajes quiso seleccionar la decisión, cuáles representó el servidor al consumir el conjunto y cuáles recibieron realmente el efecto?». RFC 5182 resuelve el transporte de una lista. La organización sigue siendo responsable de resolver la verdad de la operación.

Fuentes

  1. RFC 5182 — HTML
  2. RFC 5182 — texto plano
  3. Página informativa de RFC Editor
  4. Documento en IETF Datatracker
  5. Historial en IETF Datatracker
  6. Referencias en IETF Datatracker
  7. Erratas de RFC 5182
  8. RFC 9051 — IMAP4rev2
  9. Página informativa de RFC 9051
  10. RFC 4731 — ESEARCH
  11. RFC 4466 — ABNF recopilada de IMAP
  12. RFC 4315 — UIDPLUS
  13. RFC 3501 — IMAP4rev1
  14. RFC 5267 — IMAP CONTEXT
  15. RFC 9738 — MESSAGELIMIT
  16. RFC 9394 — PARTIAL
  17. Registro de capacidades IMAP de IANA
  18. Heng Lu — capas de realidad
  19. Heng Lu — especificación inicial mínima y adopción voluntaria
  20. Heng Lu — primacía del código en ejecución