Files
SergioandClaude Opus 4.8 703ae70235 M4: adaptador soberano con API congelada y contrato honesto
Unifica todo el proyecto tras adapter::SovereignAccount, con las precondiciones
del contrato §H en el centro:
- SubstrateCapabilities + AdapterError: open() REHÚSA (NoDurability /
  NoDeviceIdentity) si el sustrato no cumple, en vez de prometer seguridad que
  no tiene. La negativa es parte del diseño.
- Compone las piezas: EscrowState (presupuesto con procedencia, T10a) + WAL
  durable por dispositivo (T11b) + ruteo edge-local por el nervio (T9b/T10b) +
  época de fencing (T11c).
- API: spend (local | rebalanceo | Rejected{spendable}, fail-safe), available,
  value/invariant_holds (certificado value≥floor), recover (desde WAL),
  reboot (época), sync (Ok | CloneDetected como ALARMA, no recuperación).

M4.md: contrato congelado en tabla (cláusula → cómo se cumple → test), la API
pública, qué compone cada garantía, y las fronteras dichas (no previene clon;
no hay disponibilidad ilimitada bajo partición; no es motor de replicación).

Nerve ahora deriva Clone. 81 tests, clippy limpio.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 00:01:52 +00:00

4.3 KiB
Raw Permalink Blame History

M4 — el adaptador soberano (API congelada)

El puente a los sistemas soberanos (Tawasuyu/Hammer). Unifica todo el proyecto tras una API estable, adapter::SovereignAccount, con precondiciones honestas. No se declara completo hasta que el contrato de abajo se sostiene bajo los tests que lo respaldan (adapter::tests).

El contrato (§H de T9/T10/T11) — escrito en piedra

Cláusula Cómo se cumple Respaldo
Requiere WAL durable de spent por dispositivo open rehúsa con NoDurability si caps.durable_per_device == false rehusa_sin_durabilidad
Requiere identidad = conjunto de dispositivos open rehúsa con NoDeviceIdentity si caps.identity_as_devices == false rehusa_sin_identidad_por_dispositivo
Garantiza seguridad coordination-free del invariante value() ≥ floor en toda ejecución (Σ b0 conservado, gastos guardados) certificado_gastando_todo_el_slack
Acota y detecta (no previene) el clon sync devuelve CloneDetected; el daño ya ocurrió, es alarma (BOUNDARY.md) clon_detectado_en_sync
Limita la disponibilidad bajo partición spend devuelve Rejected { spendable }; nunca sobregira ni cuelga particion_sin_ruta_es_fail_safe
Rehúsa en vez de prometer de más open devuelve Err(AdapterError), no una cuenta insegura ambos rehusa_*

La API pública congelada

SubstrateCapabilities { durable_per_device, identity_as_devices }
AdapterError { NoDurability, NoDeviceIdentity, InvalidSplit }

SovereignAccount::open(caps, inv, weights, edges) -> Result<Self, AdapterError>
    // rehúsa si el sustrato no cumple; reparte el slack en celdas-dispositivo.

  .spend(device, amount) -> SpendOutcome        // Local | rebalanceo | Rejected{spendable}
  .available(device) -> i64                     // presupuesto local
  .total_available() -> i64                     // Σ b0  Σ spent
  .value() -> i64                               // inicial  Σ spent (≥ floor: certificado)
  .invariant_holds() -> bool
  .recover(device)                              // restaura spent desde el WAL tras crash
  .reboot(device) -> u64                        // incrementa la época device-local (fencing)
  .sync(&other) -> MergeOutcome                 // Ok | CloneDetected (alarma)

Qué compone (y de dónde sale cada garantía)

  • Presupuesto con procedenciaescrow::EscrowState (T10a): crash-safe y merge-safe; Σ avail = Σ b0 Σ spent invariante a las transferencias.
  • Durabilidaddurable::WriteAheadLog (T11b): el spend persiste al WAL antes del ack; recover restaura ≥ último ack. Sin ella, open rehúsa.
  • Ruteo edge-localnerve + transferencias grant (T9b/T10b): spend rebalancea de vecinas con excedente, transaccional (o rechaza, no cuelga).
  • Réplica-por-dispositivoescrow::Identity (T11a): la cuenta ES la identidad; cada dispositivo, una celda single-writer.
  • Fencing / clon — época device-local + syncMergeOutcome::CloneDetected (T11c). Detalle del daño acotado a una celda en fencing.rs.

Lo que M4 NO promete (las fronteras, dichas)

  • No previene el doble gasto por clon. Lo acota (una celda) y lo delata. CloneDetected es una alarma, no una recuperación: el dinero ya salió, la compensación vive en la capa de aplicación y puede fracasar (BOUNDARY.md).
  • No hay disponibilidad ilimitada bajo partición. Cada dispositivo se limita a su presupuesto local; diffuse (ruteo proactivo, router.rs) lo mitiga, no lo elimina (AVAILABILITY.md). CAP: safety > availability.
  • No es un motor de replicación. No hay red real ni wire protocol: es la capa de decisión coordination-free que el sustrato soberano invoca. La persistencia y el transporte los provee Tawasuyu/Hammer; el adaptador exige que la persistencia sea durable-por-dispositivo, o rehúsa.

El enunciado, una última vez

Seguridad coordination-free módulo un supuesto físico nombrado: un escritor durable por celda. Bajo él, el certificado dinámico de T10 aplica sin coordinación. Roto (clon), el daño está acotado a una celda por clon no detectado y se detecta al reconectar. No "seguro pase lo que pase" — seguro salvo esta condición física, con el costo exacto de romperla escrito en BOUNDARY.md y AVAILABILITY.md.