Feature: Resource handler sandbox and checkpoint operations
  Tests for create_sandbox (idempotent), create_checkpoint, rollback_to,
  and project_access methods on GitCheckoutHandler, FsDirectoryHandler,
  and base handler NotImplementedError defaults.

  Issue #836: ResourceHandler sandbox and checkpoint methods.

  # ============================================================
  # FsDirectory sandbox lifecycle
  # ============================================================

  Scenario: FsDirectory handler create_sandbox provisions a copy-on-write sandbox
    Given rh836- a temp directory with file "data.txt" containing "original"
    And rh836- an fs-directory resource and sandbox manager
    When rh836- I call create_sandbox on the fs-directory handler
    Then rh836- the sandbox result should be created
    And rh836- the sandbox result path should exist

  Scenario: FsDirectory handler create_sandbox is idempotent
    Given rh836- a temp directory with file "data.txt" containing "original"
    And rh836- an fs-directory resource and sandbox manager
    When rh836- I call create_sandbox on the fs-directory handler
    And rh836- I call create_sandbox on the fs-directory handler again
    Then rh836- the second sandbox result should not be created
    And rh836- both sandbox results should have the same sandbox_id

  Scenario: FsDirectory handler checkpoint and rollback cycle
    Given rh836- a temp directory with file "data.txt" containing "original"
    And rh836- an fs-directory resource and sandbox manager
    When rh836- I call create_sandbox on the fs-directory handler
    And rh836- I create a checkpoint on the fs-directory handler
    And rh836- I modify the sandbox file "data.txt" to "modified"
    And rh836- I rollback the fs-directory handler to the checkpoint
    Then rh836- the rollback result should be successful
    And rh836- the sandbox file "data.txt" should contain "original"

  # ============================================================
  # GitCheckout sandbox lifecycle
  # ============================================================

  Scenario: GitCheckout handler create_sandbox provisions a git worktree sandbox
    Given rh836- a temp git repo with file "code.py" containing "# hello"
    And rh836- a git-checkout resource and sandbox manager
    When rh836- I call create_sandbox on the git-checkout handler
    Then rh836- the sandbox result should be created
    And rh836- the sandbox result path should exist

  Scenario: GitCheckout handler checkpoint and rollback cycle
    Given rh836- a temp git repo with file "code.py" containing "# hello"
    And rh836- a git-checkout resource and sandbox manager
    When rh836- I call create_sandbox on the git-checkout handler
    And rh836- I create a checkpoint on the git-checkout handler
    And rh836- I modify the sandbox file "code.py" to "# changed"
    And rh836- I rollback the git-checkout handler to the checkpoint
    Then rh836- the rollback result should be successful
    And rh836- the sandbox file "code.py" should contain "# hello"

  # ============================================================
  # Project access
  # ============================================================

  Scenario: FsDirectory handler project_access returns permitted in local mode
    Given rh836- a temp directory with file "data.txt" containing "test"
    And rh836- an fs-directory resource and sandbox manager
    When rh836- I check project_access for principal "agent-1" action "write"
    Then rh836- the access result should be permitted
    And rh836- the access result reason should contain "local mode"

  # ============================================================
  # Base handler NotImplementedError defaults
  # ============================================================

  Scenario: Database handler create_checkpoint returns a result
    Given rh836- a database handler and dummy resource
    When rh836- I call create_checkpoint on the database handler
    Then rh836- a checkpoint result should be returned without error

  Scenario: Database handler rollback_to returns a result
    Given rh836- a database handler and dummy resource
    When rh836- I call rollback_to on the database handler
    Then rh836- a rollback result should be returned without error
