@unit Feature: ChangeSet capture and domain model As a developer using CleverAgents I want file tool mutations to be captured in a ChangeSet So that changes can be reviewed, diffed, and applied safely # ---- ChangeOperation enum ---- Scenario: ChangeOperation enum has expected members Given I import the ChangeOperation enum Then it should have members CREATE, MODIFY, DELETE, RENAME # ---- ChangeEntry model ---- Scenario: Create a ChangeEntry with all fields Given I import the ChangeEntry model When I create a ChangeEntry for a create operation Then the entry should have a ULID entry_id And the entry should have operation "create" And the entry should have a UTC timestamp And the before_hash should be None Scenario: ChangeEntry for modify operation has before and after hashes Given I import the ChangeEntry model When I create a ChangeEntry for a modify operation with hashes Then the before_hash should not be None And the after_hash should not be None Scenario: ChangeEntry for delete operation has no after_hash Given I import the ChangeEntry model When I create a ChangeEntry for a delete operation Then the after_hash should be None And the before_hash should not be None Scenario: ChangeEntry for rename operation Given I import the ChangeEntry model When I create a ChangeEntry for a rename operation Then the entry should have operation "rename" # ---- SpecChangeSet model ---- Scenario: SpecChangeSet summary counts are correct Given I import the SpecChangeSet model When I create a SpecChangeSet with mixed operations Then the creates count should be 1 And the modifies count should be 2 And the deletes count should be 1 And the renames count should be 1 And paths_changed should have 5 entries And resources_involved should have 2 entries Scenario: SpecChangeSet summary dict Given I import the SpecChangeSet model When I create a SpecChangeSet with mixed operations Then the summary dict should have correct totals Scenario: Empty SpecChangeSet has zero counts Given I import the SpecChangeSet model When I create an empty SpecChangeSet Then the creates count should be 0 And the modifies count should be 0 And the deletes count should be 0 And the renames count should be 0 # ---- InMemoryChangeSetStore ---- Scenario: InMemoryChangeSetStore start/record/get flow Given I have an InMemoryChangeSetStore When I start a changeset for plan "plan-abc" And I record a create entry in the changeset Then I can get the changeset by ID And the store changeset should have 1 entry Scenario: InMemoryChangeSetStore get_for_plan Given I have an InMemoryChangeSetStore When I start a changeset for plan "plan-abc" And I start a changeset for plan "plan-abc" And I start a changeset for plan "plan-xyz" Then get_for_plan "plan-abc" should return 2 changesets And get_for_plan "plan-xyz" should return 1 changeset Scenario: InMemoryChangeSetStore summarize Given I have an InMemoryChangeSetStore When I start a changeset for plan "plan-s" And I record a create entry in the changeset And I record a modify entry in the changeset Then the summarized changeset should show 2 total Scenario: InMemoryChangeSetStore get returns None for unknown ID Given I have an InMemoryChangeSetStore Then getting a non-existent changeset returns None Scenario: InMemoryChangeSetStore record raises on unknown ID Given I have an InMemoryChangeSetStore Then recording to a non-existent changeset raises KeyError Scenario: InMemoryChangeSetStore summarize returns empty for unknown Given I have an InMemoryChangeSetStore Then summarizing a non-existent changeset returns empty dict # ---- ChangeSetCapture integration ---- Scenario: ChangeSetCapture records resource_id and tool_name Given I have a ChangeSetCapture with resource_id "res-1" When I create a ChangeSetEntry via capture Then the entry resource_id should be "res-1" And the entry tool_name should be set Scenario: ChangeSetCapture normalizes paths Given I have a ChangeSetCapture with sandbox_root When I capture a write to a nested path Then the captured path should be repo-relative Scenario: ChangeSetCapture converts to spec changeset Given I have a ChangeSetCapture with resource_id "res-2" When I add several entries via capture Then to_spec_changeset should return a SpecChangeSet # ---- Multi-resource plan ---- Scenario: Multi-resource plan captures correctly Given I have two ChangeSetCapture instances for different resources When each capture records changes for its resource Then each changeset should only have its resource entries