Colaboración y longevidad: el Largo Ahora contra la fusión automática
Los ideales 4 y 5 exigen fusión conmutativa entre réplicas y datos que sobrevivan al producto, y esas dos exigencias tiran del formato en direcciones opuestas que hay que negociar de forma explícita.
El cuarto ideal pide que varias personas editen a la vez sin pisarse. El quinto pide que el resultado siga siendo legible dentro de veinte años, sin la empresa, sin el programa y sin la biblioteca que lo escribió. Ambos son razonables por separado. Juntos forman la tensión más interesante del marco, porque lo que hace posible la fusión automática es exactamente lo que hace opaco el formato.
- Formular el ideal 4 como conmutatividad y convergencia fuerte eventual.
- Entender el Largo Ahora como una propiedad del formato, no del programa.
- Localizar con precisión dónde chocan ambos ideales.
- Conocer las cuatro estrategias con las que se negocia el choque.
Ideal 4: colaborar sin turnos
La versión débil de la colaboración es antigua y conocida: reservar, editar, liberar. Bloqueo pesimista, control de versiones con bloqueo exclusivo, o el clásico “no toques el fichero, lo tengo yo abierto”. Funciona, y es incompatible con el ideal 3: para reservar hace falta hablar con alguien, y sin red no hay con quién hablar.
La versión fuerte, la que el ideal exige, es que dos réplicas puedan aceptar escrituras concurrentes sobre la misma región del documento y reconciliarse después sin intervención humana y sin pérdida silenciosa.
La propiedad formal que se persigue se llama convergencia fuerte eventual: dos réplicas que han recibido el mismo conjunto de actualizaciones están en el mismo estado, con independencia del orden y de las repeticiones en que las hayan recibido. Nótese la palabra conjunto. El orden de llegada no puede influir en el resultado; si influye, has construido un sistema en el que la topología de la red determina el contenido del documento.
Eso obliga a que la función de integración sea conmutativa, asociativa e idempotente. La forma habitual de conseguirlo no es escribir una función de fusión inteligente, sino cambiar la representación: en lugar de guardar el estado, se guarda el conjunto de operaciones más una regla determinista para materializarlo.
type Op = {
id: string; // generado localmente, unico
depende: string[]; // operaciones que esta replica ya habia visto
carga: unknown; // la intencion editorial
};
// El estado es funcion del CONJUNTO de operaciones, nunca del orden de llegada.
function materializar(ops: Set<Op>): Documento {
const ordenadas = ordenTotalDeterminista([...ops]);
return ordenadas.reduce(aplicar, documentoVacio());
}
Hay dos familias históricas para lograr esto. La transformación operacional ajusta cada operación entrante contra las que ya se aplicaron, y en su forma clásica se apoya en un servidor que impone un orden global, lo cual la pone en tensión con el ideal 3. Las estructuras replicadas sin conflicto trasladan la convergencia al propio tipo de dato: la operación no necesita ser transformada porque el tipo ya es conmutativo por construcción. El artículo de 2019 apostó explícitamente por esta segunda vía.
La elección entre ambas no es una cuestión de gusto sino de dónde se paga. La transformación operacional produce representaciones ligeras, muy próximas al documento final, a cambio de exigir un punto de coordinación y de tener funciones de transformación notoriamente difíciles de demostrar correctas cuando crece el número de tipos de operación. Las estructuras replicadas eliminan el punto de coordinación y hacen la corrección demostrable a nivel del tipo, a cambio de arrastrar metadatos que no desaparecen y de imponer un modelo de datos del que ya no es fácil salir. Se paga coordinación o se paga espacio; no hay una tercera opción conocida que evite ambos costes.
Que dos réplicas lleguen al mismo estado no garantiza que ese estado tenga sentido. Si dos personas reordenan concurrentemente la misma lista, el resultado convergente puede ser una intercalación que ninguna de las dos quería. La convergencia es una propiedad de consistencia; la preservación de la intención es una propiedad de semántica, y hay que diseñarla en el tipo de dato. Confundirlas es el error conceptual más común al adoptar estas estructuras.
Ideal 5: el Largo Ahora
El quinto ideal es el más fácil de enunciar y el más difícil de mantener: tus datos deben seguir siendo utilizables cuando el producto haya muerto.
La prueba es concreta y brutal: un programa escrito dentro de veinte años, por alguien sin acceso al proveedor original, ¿puede leer tus datos y extraer su contenido? Si la respuesta depende de que exista un servicio en línea, de que sobreviva una biblioteca concreta o de que alguien conserve la documentación interna de la empresa, el ideal está incumplido.
Esto convierte la longevidad en una propiedad del formato, no del programa. Y de ahí salen cuatro exigencias.
Autodescripción. Los bytes deben cargar consigo la información necesaria para interpretarse. Un volcado binario cuyo significado vive en el código fuente de la aplicación no es un formato: es un detalle de implementación expuesto.
Especificación, no solo implementación. Un formato definido como “lo que hace esta biblioteca” muere con la biblioteca. Uno definido por un documento que otra persona puede reimplementar sobrevive a su autor.
Independencia de servicio. Ninguna parte del proceso de decodificación puede requerir una llamada remota, una clave descargada ni una validación en línea.
Estabilidad frente a la evolución. Una versión nueva del programa no puede volver ilegible el fichero para versiones antiguas ni para lectores externos, salvo que la migración sea explícita, documentada y reversible.
Hay una asimetría que conviene tener presente: la longevidad no se puede añadir después. Un formato mal diseñado no se arregla retroactivamente para los ficheros que ya existen, porque esos ficheros ya están en discos ajenos y nadie va a migrarlos. Todo lo demás en un producto —la interfaz, el rendimiento, incluso el modelo de sincronización— admite reescritura; el formato en el que ya has escrito los datos de otras personas, no. Por eso el ideal 5 es el único que exige acertar temprano.
Los formatos que han sobrevivido décadas comparten un patrón: texto plano o binario documentado, estructura sencilla, y una comunidad de reimplementadores independientes. Los que han muerto comparten otro: binarios propietarios cuya semántica solo existía en un ejecutable. La lección no es “usa texto plano siempre”, que sería ingenuo para documentos ricos, sino que la longevidad se compra con redundancia semántica en el propio fichero.
Nótese también que el Largo Ahora no es solo una preocupación por el futuro lejano. Su versión cotidiana es mucho más prosaica: poder abrir tus datos con otra herramienta hoy, para un análisis puntual, para una migración parcial o para automatizar algo que el producto no contempla. Un formato que aprueba la prueba de los veinte años aprueba automáticamente esa prueba diaria, y la recíproca también funciona como indicador rápido: si nadie ha podido escribir jamás un script útil contra tus ficheros, el formato no sobrevivirá a su autor.
Dónde chocan exactamente
Aquí está la tensión, y conviene enunciarla con precisión quirúrgica en lugar de con vaguedades.
Para que la fusión automática funcione sin pérdida, la representación no puede guardar solo el estado actual. Necesita guardar identidad estable de cada elemento, contexto causal de cada operación y marcas de los elementos borrados, porque borrar no puede ser olvidar: si una réplica olvida un borrado, otra réplica que aún no lo había visto puede resucitar el elemento. El resultado es que un documento colaborativo deja de ser un documento y pasa a ser el historial de un documento más una función de materialización.
Ese cambio de naturaleza ataca el ideal 5 en tres frentes.
El primero es el volumen. Los metadatos de convergencia pueden superar con holgura al contenido útil, sobre todo en textos con mucha edición. Un archivo pesado es un archivo que se comprime, se poda o se descarta.
El segundo es la opacidad. Sin la función de materialización, los bytes no son el documento: son una traza de la que el documento se deriva. La legibilidad se vuelve dependiente de un algoritmo, y un algoritmo es mucho más difícil de reimplementar veinte años después que un esquema de campos.
El tercero es el acoplamiento a la semántica. Dos bibliotecas pueden materializar el mismo conjunto de operaciones de formas distintas si no comparten exactamente las mismas reglas de desempate. El formato ya no es solo una gramática de bytes: incluye una especificación de comportamiento concurrente.
flowchart TD I4[Ideal 4 colaboracion] --> M[Mas metadatos de convergencia] M --> M1[Identidad por elemento] M --> M2[Contexto causal] M --> M3[Marcas de borrado] M --> T[Formato mas pesado y mas opaco] T --> I5[Presion sobre el ideal 5 longevidad] style M fill:#f9e2af,color:#11111b style T fill:#f38ba8,color:#11111b
Cómo se negocia la tensión
No hay solución que elimine el choque. Hay cuatro estrategias que lo hacen manejable, y todas consisten en decidir conscientemente qué se paga.
Separar la representación de trabajo de la de archivo. El formato colaborativo optimiza la fusión; junto a él se mantiene, siempre disponible y actualizada, una proyección plana y legible del estado actual. La primera sirve para editar; la segunda es la que sobrevive. Es la estrategia con mejor relación coste-beneficio y la que más a menudo se omite por prisa.
Especificar la semántica de fusión, no solo el esquema. Si el algoritmo de materialización está documentado con el mismo rigor que la gramática de bytes, la opacidad deja de ser fatal: alguien puede reimplementarlo.
Recolectar historial de forma explícita. Se define un punto de corte a partir del cual el historial anterior se compacta en un estado base. Se pierde la capacidad de reconciliar con réplicas muy antiguas, y se gana peso y simplicidad. La clave es que sea una decisión declarada y no una consecuencia accidental.
Versionar la semántica junto al fichero. Guardar en el propio archivo qué versión de las reglas de convergencia lo produjo, para que un lector futuro sepa qué debe implementar y detecte cuándo no puede hacerlo con seguridad.
Merece la pena insistir en la primera, porque es la que más rendimiento da y la que más se descarta por parecer redundante. Mantener una proyección plana permanentemente actualizada cuesta poco —es una materialización que ya estás haciendo para pintar la interfaz— y desacopla por completo las dos exigencias: el formato colaborativo puede evolucionar, complicarse y llenarse de metadatos sin que eso comprometa la longevidad, porque la longevidad ya no descansa sobre él. Sin esa proyección, cada mejora del motor de fusión es también una degradación silenciosa del ideal 5, y el equipo ni siquiera se entera de que la está pagando.
Una regla práctica cierra el asunto: si tu documento solo existe como historial, entonces tu compromiso de longevidad depende de que alguien conserve y sepa ejecutar el algoritmo de materialización. Si existe además como estado plano, tu compromiso depende únicamente de que alguien sepa leer un formato documentado. La segunda apuesta es incomparablemente más segura a treinta años vista.
Y hay un beneficio colateral que justifica la estrategia por sí solo: la proyección plana es también el punto de integración con todo lo demás. Copias de seguridad, búsqueda con herramientas externas, control de versiones textual, revisión por terceros, análisis y automatización operan sobre ella sin conocer nada del motor de fusión. Un sistema que solo expone su historial se aísla de todo ese ecosistema; uno que expone estado plano lo hereda gratis.
Proyección plana
Exporta continuamente un estado legible sin la biblioteca. Barato y decisivo.
Semántica especificada
Documenta las reglas de desempate, no solo el formato de los bytes.
Poda declarada
Compacta el historial de forma explícita y asume el límite que impone.
La tensión entre los ideales 4 y 5 no es un defecto de las estructuras replicadas ni un problema de ingeniería pendiente de resolver: es una consecuencia de que ambos ideales tienen relaciones opuestas con el tiempo. La colaboración sin coordinación exige recordar la causalidad, porque solo sabiendo qué había visto cada réplica cuando escribió se puede reconciliar sin un árbitro; y recordar la causalidad significa acumular metadatos que crecen con la historia, no con el contenido. El archivo a largo plazo exige lo contrario: exige olvidar el proceso y conservar el resultado, porque lo que sobrevive décadas es lo simple, lo autodescriptivo y lo pequeño, no la traza completa de cómo se llegó allí. Un sistema que solo optimiza el ideal 4 produce artefactos que solo su propia biblioteca entiende, y que dejarán de entenderse cuando esa biblioteca deje de compilarse. Uno que solo optimiza el ideal 5 produce ficheros bellos que no se pueden editar entre varias personas sin un árbitro central, y ahí se pierden los ideales 3 y 4 de golpe. La única postura defendible es la doble representación: acumular mientras se colabora, olvidar deliberadamente al archivar, y tratar ese olvido como una operación de primera clase del sistema, con su propio diseño, sus propias garantías y su propia documentación. Diseñar el olvido es tan importante como diseñar la fusión.
- Define convergencia fuerte eventual y explica por qué el orden de llegada no puede influir en el estado.
- Explica por qué borrar no puede implementarse como olvidar en una réplica que aún puede recibir mensajes antiguos.
- Formula la prueba de los veinte años para un formato que uses y di si la pasa.
- Enumera tres razones concretas por las que los metadatos de convergencia dañan la longevidad.
- Diseña, en cinco líneas, la política de poda de historial de un editor colaborativo y declara qué pierdes con ella.