Commit Graph

2 Commits

Author SHA1 Message Date
HAL9000 c77f90b4ff fix(sync): add missing coverage scenarios and remove dead _iso_now from sync_models
CI / push-validation (pull_request) Successful in 26s
CI / helm (pull_request) Successful in 28s
CI / lint (pull_request) Successful in 46s
CI / quality (pull_request) Successful in 47s
CI / build (pull_request) Successful in 48s
CI / typecheck (pull_request) Successful in 1m8s
CI / security (pull_request) Successful in 1m17s
CI / integration_tests (pull_request) Failing after 2m54s
CI / unit_tests (pull_request) Failing after 4m48s
CI / coverage (pull_request) Has been skipped
CI / docker (pull_request) Has been skipped
CI / status-check (pull_request) Failing after 3s
- Remove unused _iso_now() from sync_models.py (dead code: called nowhere in
  the module; sync_service.py has its own _iso_now())
- Remove now-unused `from datetime import UTC, datetime` import
- Add 5 new BDD scenarios covering previously uncovered code paths:
  - VectorClock.happens_before() TypeError guard (sync_models.py:134-135)
  - VectorClock.is_concurrent() TypeError guard (sync_models.py:159-160)
  - process_offline_queue() PULL direction branch (sync_service.py:468-475)
  - resolve_conflict() last_writer_wins when server entity is newer (sync_service.py:549 else)
  - SyncService.push() with CLIENT_WINS resolution (_resolve_conflict lines 663-665)
- Add corresponding step implementations for the new scenarios

ISSUES CLOSED: #1125
2026-05-29 07:21:08 -04:00
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