Files
cleveragents-core/features/client/plan_sync.feature
freemo ae1fd648d5 feat(client): add plan sync and remote execution
Implement PlanSyncClient for synchronizing local resources with a remote
CleverAgents server and submitting plans for remote execution:
- Sync actions, skills, tools, projects with configurable scope flags
- Conflict resolution policies (local_wins / server_wins)
- Remote plan execution, apply, and status query endpoints
- Server-side ID persistence in local item metadata
- Sync summary output (created/updated/skipped/errors)
- Dry-run mode that skips server mutations
- SyncScope, SyncSummary, ExecutionResult data models
- Behave scenarios (18 scenarios, 62 steps)
- Robot Framework smoke tests
- ASV benchmark for sync throughput baseline
- Reference documentation at docs/reference/server_sync.md

ISSUES CLOSED: #336
2026-03-24 20:28:19 +00:00

132 lines
5.7 KiB
Gherkin

@phase2 @client @sync
Feature: Plan sync and remote execution
As a developer
I want to sync local plans with a remote server
So that I can execute plans remotely and keep state in sync
# ---------------------------------------------------------------------------
# Sync scope
# ---------------------------------------------------------------------------
Scenario: SyncScope returns all types when all flags are true
Given a SyncScope with all flags enabled
Then the active types should be "actions,skills,tools,projects"
Scenario: SyncScope returns only selected types
Given a SyncScope with only actions and tools enabled
Then the active types should be "actions,tools"
# ---------------------------------------------------------------------------
# Sync operations
# ---------------------------------------------------------------------------
Scenario: Sync creates new items on the server
Given a PlanSyncClient with a mock HTTP client
And a list of 2 new items without server_id
When I sync the items as "actions"
Then the sync summary should show 2 created and 0 updated
And the sync summary should not be a dry run
Scenario: Sync updates existing items on the server
Given a PlanSyncClient with a mock HTTP client
And a list of 2 existing items with server_id and newer version
When I sync the items as "tools"
Then the sync summary should show 0 created and 2 updated
Scenario: Sync skips items with matching version
Given a PlanSyncClient with a mock HTTP client
And a list of 1 existing items with server_id and same version
When I sync the items as "skills"
Then the sync summary should show 0 created and 0 updated and 1 skipped
Scenario: Sync dry-run does not mutate server
Given a PlanSyncClient with a mock HTTP client
And a list of 2 new items without server_id
When I sync the items as "actions" with dry_run true
Then the sync summary should show 2 created and 0 updated
And the sync summary should be a dry run
Scenario: Sync handles items missing id as errors
Given a PlanSyncClient with a mock HTTP client
And a list with one item missing id
When I sync the items as "actions"
Then the sync summary should show 0 created and 0 updated and 1 error
Scenario: Sync server_wins policy skips when server version is newer
Given a PlanSyncClient with server_wins conflict policy
And a list of 1 existing items where server version is newer
When I sync the items as "tools"
Then the sync summary should show 0 created and 0 updated and 1 skipped
# ---------------------------------------------------------------------------
# Sync all
# ---------------------------------------------------------------------------
Scenario: Sync all respects scope flags
Given a PlanSyncClient with a mock HTTP client
And resources for actions and tools
When I sync all with a scope limited to actions only
Then the sync result should contain actions but not tools
# ---------------------------------------------------------------------------
# Remote execution
# ---------------------------------------------------------------------------
Scenario: Execute plan returns execution result
Given a PlanSyncClient with a mock HTTP client for execution
When I execute plan "plan-001"
Then the execution result plan_id should be "plan-001"
And the execution result status should be "submitted"
Scenario: Apply plan returns execution result
Given a PlanSyncClient with a mock HTTP client for execution
When I apply plan "plan-002"
Then the execution result plan_id should be "plan-002"
And the execution result status should be "applying"
Scenario: Get plan status returns status dict
Given a PlanSyncClient with a mock HTTP client for status
When I get status for server plan "srv-001"
Then the plan status should contain phase "running"
Scenario: Execute plan with empty id raises ValueError
Given a PlanSyncClient with a mock HTTP client
When I execute plan with empty id
Then a ValueError should be raised for empty sync plan_id
Scenario: Apply plan with empty id raises ValueError
Given a PlanSyncClient with a mock HTTP client
When I apply plan with empty id
Then a ValueError should be raised for empty sync plan_id
Scenario: Get plan status with empty id raises ValueError
Given a PlanSyncClient with a mock HTTP client
When I get status with empty server plan id
Then a ValueError should be raised for empty sync plan_id
# ---------------------------------------------------------------------------
# Conflict policy
# ---------------------------------------------------------------------------
Scenario: Conflict policy can be changed at runtime
Given a PlanSyncClient with local_wins conflict policy
When I change the conflict policy to server_wins
Then the conflict policy should be server_wins
# ---------------------------------------------------------------------------
# SyncSummary
# ---------------------------------------------------------------------------
Scenario: SyncSummary total_processed counts all fields
Given a SyncSummary with 2 created 1 updated 1 skipped 1 errors
Then the total processed should be 5
# ---------------------------------------------------------------------------
# ExecutionResult attributes
# ---------------------------------------------------------------------------
Scenario: ExecutionResult stores all attributes
Given an ExecutionResult with plan_id "p1" server_plan_id "sp1" status "done" message "ok"
Then the execution result message should be "ok"
And the execution result server_plan_id should be "sp1"