Files
cleveragents-core/features/sandbox_merge_strategies.feature
CoreRasurae f2f7aa5dc9 feat(core): add v3 lifecycle models, automation levels, subplan support, and security hardening
Implement multiple Stage A/B/E/SEC milestones for the v3 lifecycle system:
- Stage A5.3+A5.4: Add LifecycleActionModel and LifecyclePlanModel SQLAlchemy
  models with to_domain()/from_domain() conversion methods
- Stage A5.6: Implement ActionRepository with full CRUD, namespace/state
  queries, referential integrity checks, and retry decorator
- Stage E1: Add subplan domain models (ExecutionMode, SubplanMergeStrategy,
  SubplanConfig, SubplanStatus, SubplanAttempt, SubplanFailureHandler) with
  computed properties on Plan (is_subplan, is_root_plan, depth, has_subplans)
- Stage A6: Add AutomationLevel enum (MANUAL, REVIEW_BEFORE_APPLY,
  FULL_AUTOMATION), settings integration, PlanLifecycleService auto-progression,
  pause/resume, and CLI commands (--automation-level, set-automation-level)
- Stage SEC1: Remove eval()/exec() from stream_router.py, replace with named
  operation and transform registries; code blocks and unregistered transforms
  now raise StreamRoutingError
- Add langchain-anthropic dependency
- Update BDD tests for security changes and relax ADR directory requirement
2026-02-12 20:19:42 +00:00

161 lines
6.8 KiB
Gherkin

@phase1 @infrastructure @sandbox @merge
Feature: Sandbox Merge Strategies
As a system managing parallel sandbox changes
I want multiple strategies for merging concurrent edits to the same resource
So that conflicts are detected, reported, or resolved automatically
# --- Git three-way merge ---
@git_merge
Scenario: A clean merge combines non-overlapping changes from both sides
Given a base document with three paragraphs
And one side appends a paragraph at the end
And the other side prepends a paragraph at the start
When the changes are merged using the git strategy
Then the merge should succeed without conflicts
And the merged document should contain content from both sides
@git_merge
Scenario: Overlapping edits to the same line produce a conflict
Given a base document with a single line
And one side changes the line to "alpha version"
And the other side changes the line to "beta version"
When the changes are merged using the git strategy
Then the merge should report a conflict
And the merged output should contain conflict markers
And the conflict regions should be identified with line ranges
@git_merge
Scenario: Merging three empty documents yields an empty result
Given all three merge inputs are empty
When the changes are merged using the git strategy
Then the merge should succeed without conflicts
And the merged content should be empty
@git_merge
Scenario: The git strategy cleans up temporary files after merging
Given a base document with a single line
And one side leaves the document unchanged
And the other side appends a new line
When the changes are merged using the git strategy
Then no temporary merge files should remain on disk
@git_merge
Scenario: The git strategy falls back to sequential merge when git is unavailable
Given a base document with a single line
And one side changes the line to "ours edit"
And the other side changes the line to "theirs edit"
When the changes are merged using the git strategy with git unavailable
Then the merge should succeed without conflicts
And the merged content should be the incoming side
# --- Conflict marker detection ---
@git_merge @conflict_markers
Scenario: No conflict markers are found in clean content
Given a document with no conflict markers
When the document is scanned for conflict regions
Then no conflict regions should be found
@git_merge @conflict_markers
Scenario: A single conflict region is correctly identified
Given a document containing one conflict region
When the document is scanned for conflict regions
Then exactly one conflict region should be found
And the conflict region should span the expected lines
@git_merge @conflict_markers
Scenario: Multiple conflict regions are all identified
Given a document containing two conflict regions
When the document is scanned for conflict regions
Then exactly two conflict regions should be found
# --- Sequential last-write-wins merge ---
@sequential_merge
Scenario: The incoming content always wins regardless of changes
Given a base document, a current version, and an incoming version
When the changes are merged using the sequential strategy
Then the merge should succeed without conflicts
And the merged content should be the incoming version
@sequential_merge
Scenario: An empty incoming version results in empty content
Given a base document, a current version, and an empty incoming version
When the changes are merged using the sequential strategy
Then the merged content should be empty
# --- JSON deep merge ---
@json_merge
Scenario: Non-overlapping keys from both sides are combined
Given a current JSON document with key "alpha"
And an incoming JSON document with key "beta"
When the documents are merged using the JSON strategy
Then the merge should succeed without conflicts
And the merged JSON should contain both keys
@json_merge
Scenario: A shared key is recursively merged when both values are objects
Given a current JSON document with nested object under "config"
And an incoming JSON document with additional nested keys under "config"
When the documents are merged using the JSON strategy
Then the merged JSON "config" should contain keys from both sides
@json_merge
Scenario: A shared scalar key is overwritten by the incoming value
Given a current JSON document with "version" set to 1
And an incoming JSON document with "version" set to 2
When the documents are merged using the JSON strategy
Then the merged JSON "version" should be the incoming value
@json_merge
Scenario: Arrays are replaced by the incoming side in replace mode
Given a current JSON document with an array under "items"
And an incoming JSON document with a different array under "items"
When the documents are merged using the JSON strategy in replace mode
Then the merged JSON "items" should be the incoming array
@json_merge
Scenario: Arrays are concatenated in concat mode
Given a current JSON document with an array under "items"
And an incoming JSON document with a different array under "items"
When the documents are merged using the JSON strategy in concat mode
Then the merged JSON "items" should contain elements from both arrays
@json_merge
Scenario: Invalid JSON in one document produces a failed merge
Given a current document containing invalid JSON
And an incoming JSON document with key "valid"
When the documents are merged using the JSON strategy
Then the merge should fail
And the failed merge content should fall back to the incoming text
@json_merge
Scenario: An empty current document is treated as an empty object
Given an empty current JSON document
And an incoming JSON document with key "data"
When the documents are merged using the JSON strategy
Then the merge should succeed without conflicts
And the merged JSON should contain key "data"
@json_merge
Scenario: An empty incoming document is treated as an empty object
Given a current JSON document with key "existing"
And an empty incoming JSON document
When the documents are merged using the JSON strategy
Then the merge should succeed without conflicts
And the merged JSON should contain key "existing"
@json_merge
Scenario: An unrecognized array mode is rejected during configuration
When the JSON strategy is configured with an invalid array mode
Then a configuration error should be raised
@json_merge
Scenario: A type mismatch between sides is resolved by the incoming value
Given a current JSON document with "field" as a string
And an incoming JSON document with "field" as a number
When the documents are merged using the JSON strategy
Then the merged JSON "field" should be the incoming number value