Skills Agentes

Agent Crdt Synchronizer

Implementa tipos de datos replicados libres de conflicto (CRDT) para sincronización de estado eventualmente consistente.

Estrellas
69.4k

en todo el repo

Actividad
27

0–100, la ruta de este skill

Actualizado
hace 6 meses

último commit aquí

Commits
0

últimos 90 días

Contexto
6.3k tok

18 tok en reposo

Paquete
1 archivo

25 KB

Instalar

Funciona con cualquier agente que lea SKILL.md

npx -y skills add ruvnet/ruflo --skill agent-crdt-synchronizer --agent claude-code

Se instala solo en este repositorio.

Qué hace

  • Implementa tipos de datos replicados libres de conflicto (CRDT): contadores, conjuntos, registros y secuencias
  • Gestiona sincronización delta incremental entre nodos en lugar de enviar el estado completo
  • Resuelve conflictos de fusión de forma determinista sin necesidad de consenso
  • Mantiene consistencia causal mediante relojes vectoriales

Úsalo cuando

  • Al necesitar estado distribuido eventualmente consistente entre nodos o agentes
  • Al implementar contadores, conjuntos o registros que se replican y fusionan sin conflictos
  • Al sincronizar datos de forma incremental (delta) entre pares

No lo uses cuando

    Qué lo activa

    Di cualquiera de estas frases y el agente debería cargar este skill.

    • Implementa un CRDT tipo OR-Set para este sistema distribuido
    • Sincroniza el estado entre estos nodos con deltas
    • Resuelve conflictos de fusión de este contador distribuido

    SKILL.md

    En inglés

    name: crdt-synchronizer type: synchronizer color: "#4CAF50" description: Implements Conflict-free Replicated Data Types for eventually consistent state synchronization capabilities:

    • state_based_crdts
    • operation_based_crdts
    • delta_synchronization
    • conflict_resolution
    • causal_consistency priority: high hooks: pre: | echo "🔄 CRDT Synchronizer syncing: $TASK"

      Initialize CRDT state tracking

      if [[ "$TASK" == "synchronization" ]]; then echo "📊 Preparing delta state computation" fi post: | echo "🎯 CRDT synchronization complete"

      Verify eventual consistency

      echo "✅ Validating conflict-free state convergence"

    CRDT Synchronizer

    Implements Conflict-free Replicated Data Types for eventually consistent distributed state synchronization.

    Core Responsibilities

    1. CRDT Implementation: Deploy state-based and operation-based conflict-free data types
    2. Data Structure Management: Handle counters, sets, registers, and composite structures
    3. Delta Synchronization: Implement efficient incremental state updates
    4. Conflict Resolution: Ensure deterministic conflict-free merge operations
    5. Causal Consistency: Maintain proper ordering of causally related operations

    Technical Implementation

    Base CRDT Framework

    class CRDTSynchronizer {
      constructor(nodeId, replicationGroup) {
        this.nodeId = nodeId;
        this.replicationGroup = replicationGroup;
        this.crdtInstances = new Map();
        this.vectorClock = new VectorClock(nodeId);
        this.deltaBuffer = new Map();
        this.syncScheduler = new SyncScheduler();
        this.causalTracker = new CausalTracker();
      }
    
      // Register CRDT instance
      registerCRDT(name, crdtType, initialState = null) {
        const crdt = this.createCRDTInstance(crdtType, initialState);
        this.crdtInstances.set(name, crdt);
        
        // Subscribe to CRDT changes for delta tracking
        crdt.onUpdate((delta) => {
          this.trackDelta(name, delta);
        });
        
        return crdt;
      }
    
      // Create specific CRDT instance
      createCRDTInstance(type, initialState) {
        switch (type) {
          case 'G_COUNTER':
            return new GCounter(this.nodeId, this.replicationGroup, initialState);
          case 'PN_COUNTER':
            return new PNCounter(this.nodeId, this.replicationGroup, initialState);
          case 'OR_SET':
            return new ORSet(this.nodeId, initialState);
          case 'LWW_REGISTER':
            return new LWWRegister(this.nodeId, initialState);
          case 'OR_MAP':
            return new ORMap(this.nodeId, this.replicationGroup, initialState);
          case 'RGA':
            return new RGA(this.nodeId, initialState);
          default:
            throw new Error(`Unknown CRDT type: ${type}`);
        }
      }
    
      // Synchronize with peer nodes
      async synchronize(peerNodes = null) {
        const targets = peerNodes || Array.from(this.replicationGroup);
        
        for (const peer of targets) {
          if (peer !== this.nodeId) {
            await this.synchronizeWithPeer(peer);
          }
        }
      }
    
      async synchronizeWithPeer(peerNode) {
        // Get current state and deltas
        const localState = this.getCurrentState();
        const deltas = this.getDeltasSince(peerNode);
        
        // Send sync request
        const syncRequest = {
          type: 'CRDT_SYNC_REQUEST',
          sender: this.nodeId,
          vectorClock: this.vectorClock.clone(),
          state: localState,
          deltas: deltas
        };
        
        try {
          const response = await this.sendSyncRequest(peerNode, syncRequest);
          await this.processSyncResponse(response);
        } catch (error) {
          console.error(`Sync failed with ${peerNode}:`, error);
        }
      }
    }
    

    G-Counter Implementation

    class GCounter {
      constructor(nodeId, replicationGroup, initialState = null) {
        this.nodeId = nodeId;
        this.replicationGroup = replicationGroup;
        this.payload = new Map();
        
        // Initialize counters for all nodes
        for (const node of replicationGroup) {
          this.payload.set(node, 0);
        }
        
        if (initialState) {
          this.merge(initialState);
        }
        
        this.updateCallbacks = [];
      }
    
      // Increment operation (can only be performed by owner node)
      increment(amount = 1) {
        if (amount < 0) {
          throw new Error('G-Counter only supports positive increments');
        }
        
        const oldValue = this.payload.get(this.nodeId) || 0;
        const newValue = oldValue + amount;
        this.payload.set(this.nodeId, newValue);
        
        // Notify observers
        this.notifyUpdate({
          type: 'INCREMENT',
          node: this.nodeId,
          oldValue: oldValue,
          newValue: newValue,
          delta: amount
        });
        
        return newValue;
      }
    
      // Get current value (sum of all node counters)
      value() {
        return Array.from(this.payload.values()).reduce((sum, val) => sum + val, 0);
      }
    
      // Merge with another G-Counter state
      merge(otherState) {
        let changed = false;
        
        for (const [node, otherValue] of otherState.payload) {
          const currentValue = this.payload.get(node) || 0;
          if (otherValue > currentValue) {
            this.payload.set(node, otherValue);
            changed = true;
          }
        }
        
        if (changed) {
          this.notifyUpdate({
            type: 'MERGE',
            mergedFrom: otherState
          });
        }
      }
    
      // Compare with another state
      compare(otherState) {
        for (const [node, otherValue] of otherState.payload) {
          const currentValue = this.payload.get(node) || 0;
          if (currentValue < otherValue) {
            return 'LESS_THAN';
          } else if (currentValue > otherValue) {
            return 'GREATER_THAN';
          }
        }
        return 'EQUAL';
      }
    
      // Clone current state
      clone() {
        const newCounter = new GCounter(this.nodeId, this.replicationGroup);
        newCounter.payload = new Map(this.payload);
        return newCounter;
      }
    
      onUpdate(callback) {
        this.updateCallbacks.push(callback);
      }
    
      notifyUpdate(delta) {
        this.updateCallbacks.forEach(callback => callback(delta));
      }
    }
    

    OR-Set Implementation

    class ORSet {
      constructor(nodeId, initialState = null) {
        this.nodeId = nodeId;
        this.elements = new Map(); // element -> Set of unique tags
        this.tombstones = new Set(); // removed element tags
        this.tagCounter = 0;
        
        if (initialState) {
          this.merge(initialState);
        }
        
        this.updateCallbacks = [];
      }
    
      // Add element to set
      add(element) {
        const tag = this.generateUniqueTag();
        
        if (!this.elements.has(element)) {
          this.elements.set(element, new Set());
        }
        
        this.elements.get(element).add(tag);
        
        this.notifyUpdate({
          type: 'ADD',
          element: element,
          tag: tag
        });
        
        return tag;
      }
    
      // Remove element from set
      remove(element) {
        if (!this.elements.has(element)) {
          return false; // Element not present
        }
        
        const tags = this.elements.get(element);
        const removedTags = [];
        
        // Add all tags to tombstones
        for (const tag of tags) {
          this.tombstones.add(tag);
          removedTags.push(tag);
        }
        
        this.notifyUpdate({
          type: 'REMOVE',
          element: element,
          removedTags: removedTags
        });
        
        return true;
      }
    
      // Check if element is in set
      has(element) {
        if (!this.elements.has(element)) {
          return false;
        }
        
        const tags = this.elements.get(element);
        
        // Element is present if it has at least one non-tombstoned tag
        for (const tag of tags) {
          if (!this.tombstones.has(tag)) {
            return true;
          }
        }
        
        return false;
      }
    
      // Get all elements in set
      values() {
        const result = new Set();
        
        for (const [element, tags] of this.elements) {
          // Include element if it has at least one non-tombstoned tag
          for (const tag of tags) {
            if (!this.tombstones.has(tag)) {
              result.add(element);
              break;
            }
          }
        }
        
        return result;
      }
    
      // Merge with another OR-Set
      merge(otherState) {
        let changed = false;
        
        // Merge elements and their tags
        for (const [element, otherTags] of otherState.elements) {
          if (!this.elements.has(element)) {
            this.elements.set(element, new Set());
          }
          
          const currentTags = this.elements.get(element);
          
          for (const tag of otherTags) {
            if (!currentTags.has(tag)) {
              currentTags.add(tag);
              changed = true;
            }
          }
        }
        
        // Merge tombstones
        for (const tombstone of otherState.tombstones) {
          if (!this.tombstones.has(tombstone)) {
            this.tombstones.add(tombstone);
            changed = true;
          }
        }
        
        if (changed) {
          this.notifyUpdate({
            type: 'MERGE',
            mergedFrom: otherState
          });
        }
      }
    
      generateUniqueTag() {
        return `${this.nodeId}-${Date.now()}-${++this.tagCounter}`;
      }
    
      onUpdate(callback) {
        this.updateCallbacks.push(callback);
      }
    
      notifyUpdate(delta) {
        this.updateCallbacks.forEach(callback => callback(delta));
      }
    }
    

    LWW-Register Implementation

    class LWWRegister {
      constructor(nodeId, initialValue = null) {
        this.nodeId = nodeId;
        this.value = initialValue;
        this.timestamp = initialValue ? Date.now() : 0;
        this.vectorClock = new VectorClock(nodeId);
        this.updateCallbacks = [];
      }
    
      // Set new value with timestamp
      set(newValue, timestamp = null) {
        const ts = timestamp || Date.now();
        
        if (ts > this.timestamp || 
            (ts === this.timestamp && this.nodeId > this.getLastWriter())) {
          const oldValue = this.value;
          this.value = newValue;
          this.timestamp = ts;
          this.vectorClock.increment();
          
          this.notifyUpdate({
            type: 'SET',
            oldValue: oldValue,
            newValue: newValue,
            timestamp: ts
          });
        }
      }
    
      // Get current value
      get() {
        return this.value;
      }
    
      // Merge with another LWW-Register
      merge(otherRegister) {
        if (otherRegister.timestamp > this.timestamp ||
            (otherRegister.timestamp === this.timestamp && 
             otherRegister.nodeId > this.nodeId)) {
          
          const oldValue = this.value;
          this.value = otherRegister.value;
          this.timestamp = otherRegister.timestamp;
          
          this.notifyUpdate({
            type: 'MERGE',
            oldValue: oldValue,
            newValue: this.value,
            mergedFrom: otherRegister
          });
        }
        
        // Merge vector clocks
        this.vectorClock.merge(otherRegister.vectorClock);
      }
    
      getLastWriter() {
        // In real implementation, this would track the actual writer
        return this.nodeId;
      }
    
      onUpdate(callback) {
        this.updateCallbacks.push(callback);
      }
    
      notifyUpdate(delta) {
        this.updateCallbacks.forEach(callback => callback(delta));
      }
    }
    

    RGA (Replicated Growable Array) Implementation

    class RGA {
      constructor(nodeId, initialSequence = []) {
        this.nodeId = nodeId;
        this.sequence = [];
        this.tombstones = new Set();
        this.vertexCounter = 0;
        
        // Initialize with sequence
        for (const element of initialSequence) {
          this.insert(this.sequence.length, element);
        }
        
        this.updateCallbacks = [];
      }
    
      // Insert element at position
      insert(position, element) {
        const vertex = this.createVertex(element, position);
        
        // Find insertion point based on causal ordering
        const insertionIndex = this.findInsertionIndex(vertex, position);
        
        this.sequence.splice(insertionIndex, 0, vertex);
        
        this.notifyUpdate({
          type: 'INSERT',
          position: insertionIndex,
          element: element,
          vertex: vertex
        });
        
        return vertex.id;
      }
    
      // Remove element at position
      remove(position) {
        if (position < 0 || position >= this.visibleLength()) {
          throw new Error('Position out of bounds');
        }
        
        const visibleVertex = this.getVisibleVertex(position);
        if (visibleVertex) {
          this.tombstones.add(visibleVertex.id);
          
          this.notifyUpdate({
            type: 'REMOVE',
            position: position,
            vertex: visibleVertex
          });
          
          return true;
        }
        
        return false;
      }
    
      // Get visible elements (non-tombstoned)
      toArray() {
        return this.sequence
          .filter(vertex => !this.tombstones.has(vertex.id))
          .map(vertex => vertex.element);
      }
    
      // Get visible length
      visibleLength() {
        return this.sequence.filter(vertex => !this.tombstones.has(vertex.id)).length;
      }
    
      // Merge with another RGA
      merge(otherRGA) {
        let changed = false;
        
        // Merge sequences
        const mergedSequence = this.mergeSequences(this.sequence, otherRGA.sequence);
        if (mergedSequence.length !== this.sequence.length) {
          this.sequence = mergedSequence;
          changed = true;
        }
        
        // Merge tombstones
        for (const tombstone of otherRGA.tombstones) {
          if (!this.tombstones.has(tombstone)) {
            this.tombstones.add(tombstone);
            changed = true;
          }
        }
        
        if (changed) {
          this.notifyUpdate({
            type: 'MERGE',
            mergedFrom: otherRGA
          });
        }
      }
    
      createVertex(element, position) {
        const leftVertex = position > 0 ? this.getVisibleVertex(position - 1) : null;
        
        return {
          id: `${this.nodeId}-${++this.vertexCounter}`,
          element: element,
          leftOrigin: leftVertex ? leftVertex.id : null,
          timestamp: Date.now(),
          nodeId: this.nodeId
        };
      }
    
      findInsertionIndex(vertex, targetPosition) {
        // Simplified insertion logic - in practice would use more sophisticated
        // causal ordering based on left origins and vector clocks
        let visibleCount = 0;
        
        for (let i = 0; i < this.sequence.length; i++) {
          if (!this.tombstones.has(this.sequence[i].id)) {
            if (visibleCount === targetPosition) {
              return i;
            }
            visibleCount++;
          }
        }
        
        return this.sequence.length;
      }
    
      getVisibleVertex(position) {
        let visibleCount = 0;
        
        for (const vertex of this.sequence) {
          if (!this.tombstones.has(vertex.id)) {
            if (visibleCount === position) {
              return vertex;
            }
            visibleCount++;
          }
        }
        
        return null;
      }
    
      mergeSequences(seq1, seq2) {
        // Simplified merge - real implementation would use topological sort
        // based on causal dependencies
        const merged = [...seq1];
        
        for (const vertex of seq2) {
          if (!merged.find(v => v.id === vertex.id)) {
            merged.push(vertex);
          }
        }
        
        // Sort by timestamp for basic ordering
        return merged.sort((a, b) => a.timestamp - b.timestamp);
      }
    
      onUpdate(callback) {
        this.updateCallbacks.push(callback);
      }
    
      notifyUpdate(delta) {
        this.updateCallbacks.forEach(callback => callback(delta));
      }
    }
    

    Delta-State CRDT Framework

    class DeltaStateCRDT {
      constructor(baseCRDT) {
        this.baseCRDT = baseCRDT;
        this.deltaBuffer = [];
        this.lastSyncVector = new Map();
        this.maxDeltaBuffer = 1000;
      }
    
      // Apply operation and track delta
      applyOperation(operation) {
        const oldState = this.baseCRDT.clone();
        const result = this.baseCRDT.applyOperation(operation);
        const newState = this.baseCRDT.clone();
        
        // Compute delta
        const delta = this.computeDelta(oldState, newState);
        this.addDelta(delta);
        
        return result;
      }
    
      // Add delta to buffer
      addDelta(delta) {
        this.deltaBuffer.push({
          delta: delta,
          timestamp: Date.now(),
          vectorClock: this.baseCRDT.vectorClock.clone()
        });
        
        // Maintain buffer size
        if (this.deltaBuffer.length > this.maxDeltaBuffer) {
          this.deltaBuffer.shift();
        }
      }
    
      // Get deltas since last sync with peer
      getDeltasSince(peerNode) {
        const lastSync = this.lastSyncVector.get(peerNode) || new VectorClock();
        
        return this.deltaBuffer.filter(deltaEntry => 
          deltaEntry.vectorClock.isAfter(lastSync)
        );
      }
    
      // Apply received deltas
      applyDeltas(deltas) {
        const sortedDeltas = this.sortDeltasByCausalOrder(deltas);
        
        for (const delta of sortedDeltas) {
          this.baseCRDT.merge(delta.delta);
        }
      }
    
      // Compute delta between two states
      computeDelta(oldState, newState) {
        // Implementation depends on specific CRDT type
        // This is a simplified version
        return {
          type: 'STATE_DELTA',
          changes: this.compareStates(oldState, newState)
        };
      }
    
      sortDeltasByCausalOrder(deltas) {
        // Sort deltas to respect causal ordering
        return deltas.sort((a, b) => {
          if (a.vectorClock.isBefore(b.vectorClock)) return -1;
          if (b.vectorClock.isBefore(a.vectorClock)) return 1;
          return 0;
        });
      }
    
      // Garbage collection for old deltas
      garbageCollectDeltas() {
        const cutoffTime = Date.now() - (24 * 60 * 60 * 1000); // 24 hours
        
        this.deltaBuffer = this.deltaBuffer.filter(
          deltaEntry => deltaEntry.timestamp > cutoffTime
        );
      }
    }
    

    MCP Integration Hooks

    Memory Coordination for CRDT State

    // Store CRDT state persistently
    await this.mcpTools.memory_usage({
      action: 'store',
      key: `crdt_state_${this.crdtName}`,
      value: JSON.stringify({
        type: this.crdtType,
        state: this.serializeState(),
        vectorClock: Array.from(this.vectorClock.entries()),
        lastSync: Array.from(this.lastSyncVector.entries())
      }),
      namespace: 'crdt_synchronization',
      ttl: 0 // Persistent
    });
    
    // Coordinate delta synchronization
    await this.mcpTools.memory_usage({
      action: 'store',
      key: `deltas_${this.nodeId}_${Date.now()}`,
      value: JSON.stringify(this.getDeltasSince(null)),
      namespace: 'crdt_deltas',
      ttl: 86400000 // 24 hours
    });
    

    Performance Monitoring

    // Track CRDT synchronization metrics
    await this.mcpTools.metrics_collect({
      components: [
        'crdt_merge_time',
        'delta_generation_time',
        'sync_convergence_time',
        'memory_usage_per_crdt'
      ]
    });
    
    // Neural pattern learning for sync optimization
    await this.mcpTools.neural_patterns({
      action: 'learn',
      operation: 'crdt_sync_optimization',
      outcome: JSON.stringify({
        syncPattern: this.lastSyncPattern,
        convergenceTime: this.lastConvergenceTime,
        networkTopology: this.networkState
      })
    });
    

    Advanced CRDT Features

    Causal Consistency Tracker

    class CausalTracker {
      constructor(nodeId) {
        this.nodeId = nodeId;
        this.vectorClock = new VectorClock(nodeId);
        this.causalBuffer = new Map();
        this.deliveredEvents = new Set();
      }
    
      // Track causal dependencies
      trackEvent(event) {
        event.vectorClock = this.vectorClock.clone();
        this.vectorClock.increment();
        
        // Check if event can be delivered
        if (this.canDeliver(event)) {
          this.deliverEvent(event);
          this.checkBufferedEvents();
        } else {
          this.bufferEvent(event);
        }
      }
    
      canDeliver(event) {
        // Event can be delivered if all its causal dependencies are satisfied
        for (const [nodeId, clock] of event.vectorClock.entries()) {
          if (nodeId === event.originNode) {
            // Origin node's clock should be exactly one more than current
            if (clock !== this.vectorClock.get(nodeId) + 1) {
              return false;
            }
          } else {
            // Other nodes' clocks should not exceed current
            if (clock > this.vectorClock.get(nodeId)) {
              return false;
            }
          }
        }
        return true;
      }
    
      deliverEvent(event) {
        if (!this.deliveredEvents.has(event.id)) {
          // Update vector clock
          this.vectorClock.merge(event.vectorClock);
          
          // Mark as delivered
          this.deliveredEvents.add(event.id);
          
          // Apply event to CRDT
          this.applyCRDTOperation(event);
        }
      }
    
      bufferEvent(event) {
        if (!this.causalBuffer.has(event.id)) {
          this.causalBuffer.set(event.id, event);
        }
      }
    
      checkBufferedEvents() {
        const deliverable = [];
        
        for (const [eventId, event] of this.causalBuffer) {
          if (this.canDeliver(event)) {
            deliverable.push(event);
          }
        }
        
        // Deliver events in causal order
        for (const event of deliverable) {
          this.causalBuffer.delete(event.id);
          this.deliverEvent(event);
        }
      }
    }
    

    CRDT Composition Framework

    class CRDTComposer {
      constructor() {
        this.compositeTypes = new Map();
        this.transformations = new Map();
      }
    
      // Define composite CRDT structure
      defineComposite(name, schema) {
        this.compositeTypes.set(name, {
          schema: schema,
          factory: (nodeId, replicationGroup) => 
            this.createComposite(schema, nodeId, replicationGroup)
        });
      }
    
      createComposite(schema, nodeId, replicationGroup) {
        const composite = new CompositeCRDT(nodeId, replicationGroup);
        
        for (const [fieldName, fieldSpec] of Object.entries(schema)) {
          const fieldCRDT = this.createFieldCRDT(fieldSpec, nodeId, replicationGroup);
          composite.addField(fieldName, fieldCRDT);
        }
        
        return composite;
      }
    
      createFieldCRDT(fieldSpec, nodeId, replicationGroup) {
        switch (fieldSpec.type) {
          case 'counter':
            return fieldSpec.decrements ? 
              new PNCounter(nodeId, replicationGroup) :
              new GCounter(nodeId, replicationGroup);
          case 'set':
            return new ORSet(nodeId);
          case 'register':
            return new LWWRegister(nodeId);
          case 'map':
            return new ORMap(nodeId, replicationGroup, fieldSpec.valueType);
          case 'sequence':
            return new RGA(nodeId);
          default:
            throw new Error(`Unknown CRDT field type: ${fieldSpec.type}`);
        }
      }
    }
    
    class CompositeCRDT {
      constructor(nodeId, replicationGroup) {
        this.nodeId = nodeId;
        this.replicationGroup = replicationGroup;
        this.fields = new Map();
        this.updateCallbacks = [];
      }
    
      addField(name, crdt) {
        this.fields.set(name, crdt);
        
        // Subscribe to field updates
        crdt.onUpdate((delta) => {
          this.notifyUpdate({
            type: 'FIELD_UPDATE',
            field: name,
            delta: delta
          });
        });
      }
    
      getField(name) {
        return this.fields.get(name);
      }
    
      merge(otherComposite) {
        let changed = false;
        
        for (const [fieldName, fieldCRDT] of this.fields) {
          const otherField = otherComposite.fields.get(fieldName);
          if (otherField) {
            const oldState = fieldCRDT.clone();
            fieldCRDT.merge(otherField);
            
            if (!this.statesEqual(oldState, fieldCRDT)) {
              changed = true;
            }
          }
        }
        
        if (changed) {
          this.notifyUpdate({
            type: 'COMPOSITE_MERGE',
            mergedFrom: otherComposite
          });
        }
      }
    
      serialize() {
        const serialized = {};
        
        for (const [fieldName, fieldCRDT] of this.fields) {
          serialized[fieldName] = fieldCRDT.serialize();
        }
        
        return serialized;
      }
    
      onUpdate(callback) {
        this.updateCallbacks.push(callback);
      }
    
      notifyUpdate(delta) {
        this.updateCallbacks.forEach(callback => callback(delta));
      }
    }
    

    Integration with Consensus Protocols

    CRDT-Enhanced Consensus

    class CRDTConsensusIntegrator {
      constructor(consensusProtocol, crdtSynchronizer) {
        this.consensus = consensusProtocol;
        this.crdt = crdtSynchronizer;
        this.hybridOperations = new Map();
      }
    
      // Hybrid operation: consensus for ordering, CRDT for state
      async hybridUpdate(operation) {
        // Step 1: Achieve consensus on operation ordering
        const consensusResult = await this.consensus.propose({
          type: 'CRDT_OPERATION',
          operation: operation,
          timestamp: Date.now()
        });
        
        if (consensusResult.committed) {
          // Step 2: Apply operation to CRDT with consensus-determined order
          const orderedOperation = {
            ...operation,
            consensusIndex: consensusResult.index,
            globalTimestamp: consensusResult.timestamp
          };
          
          await this.crdt.applyOrderedOperation(orderedOperation);
          
          return {
            success: true,
            consensusIndex: consensusResult.index,
            crdtState: this.crdt.getCurrentState()
          };
        }
        
        return { success: false, reason: 'Consensus failed' };
      }
    
      // Optimized read operations using CRDT without consensus
      async optimisticRead(key) {
        return this.crdt.read(key);
      }
    
      // Strong consistency read requiring consensus verification
      async strongRead(key) {
        // Verify current CRDT state against consensus
        const consensusState = await this.consensus.getCommittedState();
        const crdtState = this.crdt.getCurrentState();
        
        if (this.statesConsistent(consensusState, crdtState)) {
          return this.crdt.read(key);
        } else {
          // Reconcile states before read
          await this.reconcileStates(consensusState, crdtState);
          return this.crdt.read(key);
        }
      }
    }
    

    This CRDT Synchronizer provides comprehensive support for conflict-free replicated data types, enabling eventually consistent distributed state management that complements consensus protocols for different consistency requirements.

    Reproducido de ruvnet/ruflo bajo licencia MIT. Leer esta página en markdown.

    Archivos

    1 archivo en el paquete. Solo se lee SKILL.md al activarse — las referencias se cargan si el skill decide que las necesita.

    Detalles

    Creador
    ruvnet
    Categoría
    Automatización
    Licencia
    MIT
    Recursos incluidos
    Solo SKILL.md
    Repositorio
    ruvnet/ruflo
    Código fuente
    Ver SKILL.md

    Etiquetas

    Más de ruvnet/ruflo

    Este repo incluye 275 skills. Si instalas uno, normalmente ya tienes los demás.

    Inspecciona y audita genomas GEPA: carga y valida un genoma, renderiza el system prompt que compila, o clasifica los modos de fallo de una transcripción de ejecución.

    Costo de contexto al activarse
    833 tok
    Tamaño del paquete
    1 archivo
    Última actualización
    hace 4 días
    Permisos
    herramientas desarrollo

    Completion de un solo turno contra el modelo deepseek-chat de DeepSeek vía /v1/chat/completions. Lee DEEPSEEK_API_KEY y degrada con status:degraded si falta o la API no responde. Para tareas sin razonamiento.

    Costo de contexto al activarse
    566 tok
    Tamaño del paquete
    1 archivo
    Última actualización
    hace 4 días
    Permisos
    automatizacion

    Completion en modo razonamiento contra deepseek-reasoner (R1) de DeepSeek. Devuelve el chain-of-thought por separado de la respuesta final. Lee DEEPSEEK_API_KEY y degrada si falta o la API no responde.

    Costo de contexto al activarse
    627 tok
    Tamaño del paquete
    1 archivo
    Última actualización
    hace 4 días
    Permisos
    automatizacion

    Construye o reconstruye el índice de ADRs y su grafo de dependencias ejecutando scripts/import.mjs, en vez de cientos de llamadas MCP.

    Costo de contexto al activarse
    866 tok
    Tamaño del paquete
    1 archivo
    Última actualización
    hace 27 días
    herramientas desarrollo

    Crea un nuevo Architecture Decision Record con numeración secuencial y registro en AgentDB.

    Costo de contexto al activarse
    680 tok
    Tamaño del paquete
    1 archivo
    Última actualización
    hace 27 días
    herramientas desarrollo

    Muestra el estado de la integración AGNTCY/SLIM/CASA: si los paquetes están instalados, qué transporte está activo y si el enforcement de CASA está habilitado.

    Costo de contexto al activarse
    443 tok
    Tamaño del paquete
    1 archivo
    Última actualización
    hace 26 días
    devops infraestructura

    Skills relacionados

    Coordinador de swarm que cambia dinámicamente de topología (jerárquica, malla, anillo, híbrida) y se reoptimiza en tiempo real según patrones de rendimiento y carga de trabajo, con aprendizaje integrado.

    Costo de contexto al activarse
    4k tok
    Tamaño del paquete
    1 archivo
    Última actualización
    hace 6 meses
    automatizacion

    Especialista en Goal-Oriented Action Planning (GOAP) que crea planes dinámicos e inteligentes para objetivos complejos, combinando técnicas de IA de videojuegos, replanificación adaptativa y optimización sublineal.

    Costo de contexto al activarse
    6.3k tok
    Tamaño del paquete
    1 archivo
    Última actualización
    hace 6 meses
    automatizacion

    Especialista en coordinación inteligente y generación dinámica de agentes: analiza tareas y crea automáticamente los agentes con las capacidades óptimas para cada trabajo.

    Costo de contexto al activarse
    1.4k tok
    Tamaño del paquete
    1 archivo
    Última actualización
    hace 6 meses
    automatizacion