Replace the simulated rollback in CheckpointService.rollback_to_checkpoint()
with real git operations. The method now executes git reset --hard <sandbox_ref>
followed by git clean -fd inside the sandbox working directory, reverting all
tracked file changes and removing untracked files added after the checkpoint.
Key changes:
- CheckpointService.rollback_to_checkpoint() now calls _git_reset_hard() and
_git_clean() via subprocess against the sandbox path, enforcing sandbox
boundary by confining all git operations to cwd=sandbox_path.
- Added _resolve_sandbox_path() to extract sandbox validation into a dedicated
method, supporting both lifecycle-service and in-memory fallback paths.
- Added _validate_sandbox() to verify the sandbox path is a directory containing
a .git subdirectory before executing git operations.
- Added _git_changed_paths() to compute the diff between HEAD and the target ref
before reset, providing accurate restored file counts in the result.
- Domain event emission (CHECKPOINT_RESTORED) added via the optional event_bus,
following the same EventBus protocol pattern used by other services.
- Updated existing Robot Framework helper (helper_checkpoint_rollback.py) to use
a real temporary git workspace instead of a fake sandbox path, since
_validate_sandbox() now enforces that the path is a real git repository.
- Removed @tdd_expected_fail tags from TDD test files since the bug is now fixed.
- Added new Behave scenarios and Robot integration tests for real file reversion,
file removal after rollback, domain event emission, and sandbox boundary
enforcement.
ISSUES CLOSED: #822