Files
cleveragents-core/robot/entity_sync.robot
T
freemo ff9c6540a2 feat(server): entity sync (_cleveragents/sync/*)
Implement entity synchronization between client and server using
the _cleveragents/sync/* A2A extension methods per the specification.

Sync models (src/cleveragents/a2a/sync_models.py):
- Pydantic v2 models for pull/push/status requests and responses
- VectorClock with increment, merge, happens-before, and concurrency
  detection for distributed conflict detection
- SyncEntitySnapshot, SyncConflict, SyncState, SyncQueueEntry models
- SyncEntityType enum: actor, skill, action, plan, session
- ConflictResolution enum: last_writer_wins, manual, server_wins,
  client_wins

SyncService (src/cleveragents/application/services/sync_service.py):
- pull(): download server namespace entities to local cache with
  incremental sync (since timestamps) and force-overwrite option
- push(): push local entity definitions to server namespace with
  configurable conflict resolution strategy
- status(): compare local and server entity versions, detect drift,
  report local-ahead, server-ahead, and concurrent conflicts
- resolve_conflict(): manually resolve detected conflicts with
  winner selection (local or server)
- Offline queue: enqueue_offline() and process_offline_queue() for
  retry on reconnect, with max-retries enforcement
- The local/ namespace is never synced per specification

A2A facade (src/cleveragents/a2a/facade.py):
- Replaced sync stub handlers with real _handle_sync_pull,
  _handle_sync_push, _handle_sync_status routing to SyncService
- Added sync_service property and TYPE_CHECKING import
- Facade returns stubs when no SyncService is registered

Tests:
- Behave BDD: features/entity_sync.feature (65 scenarios, 247 steps)
  covering models, vector clocks, pull/push/status, conflict resolution,
  offline queue, facade integration, constructor validation, edge cases
- Robot Framework: robot/entity_sync.robot (8 integration tests)

ISSUES CLOSED: #866
2026-05-29 07:21:08 -04:00

75 lines
3.2 KiB
Plaintext

*** Settings ***
Documentation Integration tests for entity sync (_cleveragents/sync/*)
Resource ${CURDIR}/common.resource
Suite Setup Setup Test Environment
Suite Teardown Cleanup Test Environment
*** Variables ***
${HELPER} ${CURDIR}/helper_entity_sync.py
*** Test Cases ***
Sync Pull Via Facade
[Documentation] Verify sync/pull works through A2A facade with SyncService
${result}= Run Process ${PYTHON} ${HELPER} sync-pull cwd=${WORKSPACE}
Log ${result.stdout}
Log ${result.stderr}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} sync-pull-ok
Sync Push Via Facade
[Documentation] Verify sync/push works through A2A facade with SyncService
${result}= Run Process ${PYTHON} ${HELPER} sync-push cwd=${WORKSPACE}
Log ${result.stdout}
Log ${result.stderr}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} sync-push-ok
Sync Status Via Facade
[Documentation] Verify sync/status detects drift through A2A facade
${result}= Run Process ${PYTHON} ${HELPER} sync-status cwd=${WORKSPACE}
Log ${result.stdout}
Log ${result.stderr}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} sync-status-ok
Sync Conflict Resolution
[Documentation] Verify conflict detection and resolution with vector clocks
${result}= Run Process ${PYTHON} ${HELPER} sync-conflict-resolution cwd=${WORKSPACE}
Log ${result.stdout}
Log ${result.stderr}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} sync-conflict-resolution-ok
Sync Offline Queue
[Documentation] Verify offline queue enqueue and processing
${result}= Run Process ${PYTHON} ${HELPER} sync-offline-queue cwd=${WORKSPACE}
Log ${result.stdout}
Log ${result.stderr}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} sync-offline-queue-ok
Sync Vector Clock Operations
[Documentation] Verify vector clock increment, merge, happens-before, concurrent
${result}= Run Process ${PYTHON} ${HELPER} sync-vector-clock cwd=${WORKSPACE}
Log ${result.stdout}
Log ${result.stderr}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} sync-vector-clock-ok
Sync Facade Without Service Returns Stubs
[Documentation] Verify sync operations return stubs when no SyncService is registered
${result}= Run Process ${PYTHON} ${HELPER} sync-facade-no-service cwd=${WORKSPACE}
Log ${result.stdout}
Log ${result.stderr}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} sync-facade-no-service-ok
Sync Incremental Pull
[Documentation] Verify incremental sync only pulls entities updated after since timestamp
${result}= Run Process ${PYTHON} ${HELPER} sync-incremental cwd=${WORKSPACE}
Log ${result.stdout}
Log ${result.stderr}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} sync-incremental-ok
*** Keywords ***