# Symmetric Sync Protocol Architecture

This document describes the symmetric synchronization architecture used in `ibgib`. It leverages the unique properties of ibGib (content-addressability, intrinsic timeline history) to create a robust, audit-trail-based synchronization protocol.

## Core Concepts

The synchronization process is modeled as a "Saga" — a linear but distributed conversation between two nodes.

*   **[SyncSagaIbGib_V1](file:./sync-types.mts)**: The timeline that encapsulates the entire sync process. This acts as the **shared audit trail**. By the end of a successful sync, both the Local and Remote nodes will have an identical copy of this saga timeline, proving exactly what was exchanged and when.
*   **[SyncSagaCoordinator](file:./sync-saga-coordinator.mts)**: The "Driver" (State Machine) that manages the saga. It is symmetric: both Alice (Source) and Bob (Destination) use the exact same coordinator logic to evolve the saga frame.
*   **[SyncPeerWitness](file:./sync-peer/sync-peer-types.mts)**: The interface for the "Transport Layer". It abstracts the communication channel (Method Call, HTTP, WebSocket) into a simple Witness pattern: `(SyncSagaContextIbGib_V1) => Promise<SyncSagaContextIbGib_V1>` ("ping-pong" exchange).
    *   **[SyncPeer_V1](file:./sync-peer/sync-peer-v1.mts)** provides the base plumbing.
    *   Concrete implementations (e.g., in-memory) handle the actual byte transfer.
*   **[SyncSagaContextIbGib_V1](file:./sync-saga-context/sync-saga-context-types.mts)**: The "Transport Envelope" passed to the `SyncPeer_V1`.
    * Contains the current Saga Frame, the Message Stone(s) (Data), and any cryptographic proofs required for the step.

## Workflow

Init -> Ack -> Delta(s) -> Conflict/Commit via "ping pong" exchange.

1.  **Init**: Sender initiates sync.
    * Creates the `SyncSagaIbGib_V1` with an `Init` msg frame containing knowledge about domain ibgibs to sync.
    * Optionally creates session keystone based off of Sender's primary keystone.
    * Wraps the saga ibgib in a `SyncSagaContextIbGib_V1` and passes to the `SyncPeer_V1`.
2.  **Ack**: Receiver gets incoming `SyncSagaContextIbGib_V1` and passes to its `SyncSagaCoordinator`.
    * Handles the `Init` frame, comparing knowledge with Receiver's own status of each timeline/stone in domain ibgibs.
    * Creates an `Ack` frame, evolves the `SyncSagaIbGib_V1` with this, wraps in `SyncSagaContextIbGib_V1` and returns to Sender.
      * The `Ack` frame carries both synchronization data (requests/offers) AND conflict information.
      * If the Receiver detects divergence (timeline tips differ and receiver doesn't recognize Sender's tip), it includes a `conflicts` array.
      * Each conflict includes the `tjpAddr`, `localAddr` (Receiver's Tip), `remoteAddr` (Sender's Tip), and crucially `timelineAddrs` (History).
3.  **Delta**: Sender now has enough information to send `Delta` frame if needed.
    * Both Sender and Receiver can send `Delta` frames.
    * `Delta` frames soft link to `payloadAddrsDomain` and act as a manifest, while the actual data transmitted happens according to the `SyncPeer_V1` implementation.
      * `SyncPeer_V1.payloadIbGibsDomainReceived$` is an observable for the actual domain payload ibgibs transmitted.
      * So the a node sends domain payloads out in bulk to the `SyncPeer_V1`, receives the return saga ibgib with a manifest, but may have to wait for the observable to complete to actually process the ibgibs.
    * `Delta` frame can include `requests` (e.g., asking for missing conflict history).
    * Once no deltas required, `Delta` frame sets `proposeCommit` flag. If the other has nothing to add, the session transitions to `Commit`.
4.  **Commit**: When receive `Delta` frame with `proposeCommit`,  should trigger the receiver of this to start its commit. If that is successful, it should return a `Commit` frame, which signals the commit was successful on their end. When this `Commit` frame is received, this end should not perform its own commit.
    * For local-only syncs, the `SyncPeer_V1` implementation is responsible for moving verified `ibGibs` from the temporary saga space to the durable/persistent domain space.
*   From each endpoint's POV, the cleanup should remove the temp spaces used, in addition to any other required transaction cleanup (like closing any connections).

### Session Identity (`useSessionIdentity`)

The sync protocol can optionally generate an ephemeral Keystone Identity for the duration of the saga.

**Purpose**: To allow secure, signed exchanges even if the Node doesn't have a long-lived identity, or to isolate the sync session security from master identity.

**Current Status**:
*   ✅ Session keystone creation implemented ([getSessionIdentity()](file:./sync-saga-coordinator.mts#L328-L362))
*   ✅ Keystone passed via Init message ([initData.identity](file:./sync-saga-message/sync-saga-message-types.mts#L75))
*   ⚠️ **Signature generation/verification: NOT yet implemented**
*   ⚠️ **Per-frame proof creation: NOT yet implemented**

**Usage**:
```typescript
const { done } = await coordinator.sync({
  peer,
  domainIbGibs: [timeline],
  localSpace,
  metaspace,
  useSessionIdentity: true, // Default, but currently non-functional
});
```

> [!CAUTION]
> **🚧 Session identity is NOT working yet.** Tests explicitly set `useSessionIdentity: false` to avoid failures. See [sync-innerspace-dest-ahead-withid.respec.mts](file:./sync-innerspace-dest-ahead-withid.respec.mts) for the failing test case.

**Authentication/Authorization Hooks**:

Validation occurs in [SyncPeer_V1.witness()](file:./sync-peer/sync-peer-v1.mts#L129-L219):
1. `validateContextAndSagaFrame()` - Intrinsic validation
2. `authenticateContext()` - Verify identity (stub)
3. `authorizeContext()` - Check permissions (stub)

### Conflict Resolution via Grafting

> [!IMPORTANT]
> **🔀 When timelines diverge**, the sync protocol uses **grafting** to merge branches.

**Mechanism**:
1. **Detect divergence** in Ack stage (tips differ, neither recognizes other's tip)
2. **Exchange full timeline history** via `SyncSagaConflictInfo.receiverKnowledgeTimelineAddrs`
3. **Find Latest Common Ancestor (LCA)**
4. **Replay DNA transforms** from both branches
5. **Create graft timeline** with merged result
6. **Track via** `GraftInfoIbGib_V1` ([graft-info-types.mts](file:./graft-info/graft-info-types.mts))

**Conflict Info Tracking**:
*   `graftInfoAddr`: Points to graft metadata
*   `createdDnaAddrs`: DNA ibgibs created during merge
*   `replayedDnaAddrs`: Original DNAs replayed
*   `createdDomainAddrs`: Final timeline frames (in order)

See [graft-info-helpers.mts](file:./graft-info/graft-info-helpers.mts) for implementation.

### Transaction Model (Temp Spaces)

> [!NOTE]
> **💾 Sync uses a two-phase commit pattern** with temporary spaces for atomic operations.

**Phases**:
1. **Accumulation**: Domain ibgibs received during sync go to `tempSpace`
2. **Commit**: On successful saga completion, verified ibgibs move to durable `localSpace`

**Rollback**: If saga fails, temp space cleanup discards unverified data.

**Lifecycle**:
*   **Created**: `tempSpace = await metaspace.createNewLocalSpace()` at saga start
*   **Destroyed**: Cleanup function runs in `sync()` finally block

**Why**: Ensures atomic sync - either all data validates and commits, or none does.


## 🔒 Security Considerations

> [!WARNING]
> Session identity is **currently non-functional**. The mitigations below describe the intended security model.

### Attack Vectors & Mitigations

| Attack Vector | Description | Mitigation |
|---------------|-------------|------------|
| **MITM Replay** | Attacker replays captured saga frames | • Frame signatures include timestamp<br>• Freshness checks reject old frames<br>• Challenge depletion prevents reuse<br>• sagaId deduplication |
| **Session Fixation** | Attacker pre-generates session keystone | • Session secret derived via KDF (strategy in keystone metadata)<br>• `sessionSecret = KDF(masterSecret, sagaId, strategy)` |
| **Identity Spoofing** | Impersonation via fake session keystone | • Session keystone includes `derivedFrom` master address<br>• Receiver validates master keystone is known/trusted |
| **Challenge Grinding** | Brute-force challenge solutions for target binding | • Hash pre-imaging computationally infeasible<br>• Stochastic selection adds randomness |
| **DoS (Pool Exhaustion)** | Excessive syncs deplete challenge pools | • Top-up replenishment refills challenges<br>• Rate limiting per identity<br>• Pool separation for critical ops |
| **Saga Hijacking** | Mid-flight frame injection | • All frames signed with session keystone<br>• `past` rel8n creates tamper-evident chain |

### Cryptographic Primitives

*   **Hash Function**: SHA-256 (content addressing, challenge generation)
*   **Proof System**: Hash-reveal protocol (`hash-reveal-v1`)
*   **Binding**: Target address → hex bucket → challenge selection
*   **Entropy**: Stochastic challenge selection (anti-grinding)

### Trust Model

**Session Keystones**:
- Ephemeral identity per sync saga
- Derived from master keystone + `sagaId`
- Validates via proof-of-work (solving challenges)
- Post-hoc audit trail: master can prove session authorship

**Propagation**:
- Sync does NOT rely on global PKI or certificate authorities
- Trust propagates through sync sessions (Alice syncs with Bob → Bob witnesses Alice's keystone)
- Revocation propagates same way (Alice revokes → syncs revocation to Bob → Bob sees revoked timeline)

**Threat Boundaries**:
- ✅ Protects against: MITM replay, impersonation, frame tampering
- ⚠️ Does NOT protect against: Compromised endpoint (live memory access during active session)
- ⚠️ Master secrets: Raw secrets should NOT stored; keystones master secrets to keystones should be derived secrets via key stretching passwords. raw secret files of course can drive these passwords and must be protected
- ⚠️ Transport security: Use TLS for network layer encryption (ibgib protocol provides authentication/integrity, not confidentiality)

### Best Practices

1. **Master Secret Protection**: Store master secrets in secure enclaves/keychains
2. **Session Lifetime**: Limit saga duration, revoke sessions post-completion
3. **Rate Limiting**: Implement per-identity sync rate limits
4. **Freshness**: Reject frames older than 60 seconds
5. **Audit Logs**: Persist saga timelines for post-hoc validation (saga timelines are ibgibs, so integrity is built-in via content addressing)
6. **TLS**: Always use TLS for network transport (defense-in-depth)

## 📚 Documentation
*   **[Architecture](./docs/architecture.md)**: Detailed design of the Saga Protocol, State Machine, and Smart Diff logic.
*   **[Testing & Verification](./docs/testing.md)**: Test strategy, verification matrix, and comprehensive testing guidelines.

## Features
*   **Symmetric Design**: No distinct "Client" or "Server" logic.
*   **Smart Diff**: Efficient "Knowledge Map" exchange to transfer only missing deltas (though some inefficiencies may exist early on).
*   **Timelines && Constants**: Support for syncing both mutable histories and immutable constant ibgibs.
*   **Optimistic Conflict Resolution**: (In Progress) Branch detection and merge strategies.

## Verification
We rely on rigorous In-Memory Simulation (`InnerSpace`) to verify complex graph scenarios. See **[Verification](./docs/verification.md)** for the full status.
