1# BOUNDARY — la frontera del clon (T11c, §D)
2
3El límite último del proyecto, dicho sin sobre-reclamo. Respaldado por
4`fencing::tests`.
5
6## El teorema de imposibilidad
7
8> **Ningún mecanismo local puede detectar un clon silencioso antes de que los
9> clones se comuniquen.**
10
11Un dispositivo restaurado a dos copias vivas (VM snapshot, proceso duplicado) que
12comparten `device_id` y celda y **no se comunican**: cada clon cree tener la celda
13entera y puede gastarla. Sin comunicación, no hay forma de saber que el
14presupuesto ya se gastó en la otra copia. Es el mismo **CAP** que el sobregiro
15particionado (`AVAILABILITY.md`), ahora **dentro de una celda**: bajo partición, o
16sacrificas consistencia (doble gasto) o disponibilidad (no gastas). No hay tercera
17opción, y este proyecto no finge tenerla.
18
19## Lo mejor posible: fencing por época, enforced en el merge
20
21No un servidor central (no existe en la malla), sino el propio `merge`:
22
23- Cada arranque de un dispositivo incrementa una **época** monótona, **device-local**
24 y persistida en el WAL (§B/`durable.rs`). Device-local **a propósito**: épocas
25 globalmente monótonas pedirían consenso, que es justo lo que evitamos.
26- El gasto se indexa por `(device_id, epoch)`.
27- Al fusionar, dos linajes con el mismo `device_id` y **épocas distintas** delatan
28 un clon: la época menor es la obsoleta (`MergeOutcome::CloneDetected`).
29
30## La garantía real: *bounded + detect*, no *prevent*
31
32Honestidad frente al fencing token clásico (Kleppmann): aquél asume un recurso
33**linealizable** que rechaza tokens viejos. La malla no lo tiene, por eso el
34enforcement vive en el `merge` y la garantía es más débil y honesta:
35
36| | Sin fencing | Con fencing (T11c) |
37|---|---|---|
38| Doble gasto | silencioso e **ilimitado** | **acotado** a una celda por clon no detectado |
39| Detección | nunca | **al reconectar** (en el merge) |
40
41- **No previene** el doble gasto mientras los clones están aislados — es imposible.
42- **Lo acota**: cada clon gasta ≤ su presupuesto de celda ⟹ el sobregiro es ≤ una
43 celda (`FencedCell::overspend() ≤ budget`, verificado por `proptest`).
44- **Lo delata**: `CloneDetected` en el merge. El linaje vivo (época mayor) es lo
45 único que se propaga como legítimo; los gastos del clon obsoleto quedan aislados.
46
47**`CloneDetected` es una ALARMA, no una recuperación.** El daño de una celda **ya
48ocurrió en el mundo**: el clon obsoleto entregó dinero real que no se puede
49des-entregar desde aquí. Aislar sus gastos evita que el doble conteo se propague
50como presupuesto legítimo por la malla, pero **no recupera nada**. La compensación
51(clawback, reverso, alarma humana) es un problema de la **capa de aplicación**,
52vive **fuera** de este sistema, es **coordinación**, y **puede fracasar** (el
53dinero se fue). Acotado y delatado, sí; **reversible, no necesariamente**. M4 no
54debe leer esto como "el sistema se auto-repara".
55
56Convierte "silencioso e ilimitado" en "acotado y delatado". Eso es todo lo que un
57sistema coordination-free puede ofrecer aquí — y decirlo así es el resultado.
58
59## El terminus honesto (§E)
60
61**Seguridad coordination-free módulo un supuesto físico nombrado:** cada celda de
62presupuesto tiene un único escritor durable. Bajo ese supuesto (durabilidad §B +
63réplica-por-dispositivo §C) el certificado de T10 aplica sin coordinación. Cuando
64el supuesto se rompe (clon, §D), el daño está acotado a una celda por clon no
65detectado y se detecta al reconectar. No "seguro pase lo que pase", sino "seguro
66salvo esta condición física, y aquí está exactamente qué pasa cuando se rompe y
67cuánto cuesta".
BOUNDARY.md
BOUNDARY — la frontera del clon (T11c, §D)
El límite último del proyecto, dicho sin sobre-reclamo. Respaldado por
fencing::tests.
El teorema de imposibilidad
Ningún mecanismo local puede detectar un clon silencioso antes de que los
clones se comuniquen.
Un dispositivo restaurado a dos copias vivas (VM snapshot, proceso duplicado) que
comparten device_id y celda y no se comunican: cada clon cree tener la celda
entera y puede gastarla. Sin comunicación, no hay forma de saber que el
presupuesto ya se gastó en la otra copia. Es el mismo CAP que el sobregiro
particionado (AVAILABILITY.md), ahora dentro de una celda: bajo partición, o
sacrificas consistencia (doble gasto) o disponibilidad (no gastas). No hay tercera
opción, y este proyecto no finge tenerla.
Lo mejor posible: fencing por época, enforced en el merge
No un servidor central (no existe en la malla), sino el propio merge:
- Cada arranque de un dispositivo incrementa una época monótona, device-local
y persistida en el WAL (§B/
durable.rs). Device-local a propósito: épocas
globalmente monótonas pedirían consenso, que es justo lo que evitamos.
- El gasto se indexa por
(device_id, epoch).
- Al fusionar, dos linajes con el mismo
device_id y épocas distintas delatan
un clon: la época menor es la obsoleta (MergeOutcome::CloneDetected).
La garantía real: bounded + detect, no prevent
Honestidad frente al fencing token clásico (Kleppmann): aquél asume un recurso
linealizable que rechaza tokens viejos. La malla no lo tiene, por eso el
enforcement vive en el merge y la garantía es más débil y honesta:
| Sin fencing | Con fencing (T11c) |
| Doble gasto | silencioso e ilimitado | acotado a una celda por clon no detectado |
| Detección | nunca | al reconectar (en el merge) |
- No previene el doble gasto mientras los clones están aislados — es imposible.
- Lo acota: cada clon gasta ≤ su presupuesto de celda ⟹ el sobregiro es ≤ una
celda (
FencedCell::overspend() ≤ budget, verificado por proptest).
- Lo delata:
CloneDetected en el merge. El linaje vivo (época mayor) es lo
único que se propaga como legítimo; los gastos del clon obsoleto quedan aislados.
CloneDetected es una ALARMA, no una recuperación. El daño de una celda ya
ocurrió en el mundo: el clon obsoleto entregó dinero real que no se puede
des-entregar desde aquí. Aislar sus gastos evita que el doble conteo se propague
como presupuesto legítimo por la malla, pero no recupera nada. La compensación
(clawback, reverso, alarma humana) es un problema de la capa de aplicación,
vive fuera de este sistema, es coordinación, y puede fracasar (el
dinero se fue). Acotado y delatado, sí; reversible, no necesariamente. M4 no
debe leer esto como "el sistema se auto-repara".
Convierte "silencioso e ilimitado" en "acotado y delatado". Eso es todo lo que un
sistema coordination-free puede ofrecer aquí — y decirlo así es el resultado.
El terminus honesto (§E)
Seguridad coordination-free módulo un supuesto físico nombrado: cada celda de
presupuesto tiene un único escritor durable. Bajo ese supuesto (durabilidad §B +
réplica-por-dispositivo §C) el certificado de T10 aplica sin coordinación. Cuando
el supuesto se rompe (clon, §D), el daño está acotado a una celda por clon no
detectado y se detecta al reconectar. No "seguro pase lo que pase", sino "seguro
salvo esta condición física, y aquí está exactamente qué pasa cuando se rompe y
cuánto cuesta".