## Context

Currently, all tool instances bind-mount the host repository path via `{{REPO_PATH}}` substitution in compose templates. The repository model (`GitRepository`) has no SSH key association. The instance model (`ToolInstance`) has no concept of repository access mode.

Users want two modes:
1. **Mount** (current): Live sync with working copy on host
2. **Clone** (new): Fresh isolated copy with full git history inside the container

The SSH key system already exists with encrypted private keys in the database. Keys can be project-scoped or user-scoped.

## Goals / Non-Goals

**Goals:**
- Allow per-instance choice between mount and clone mode
- Support branch selection for clone mode (default: main)
- Enable git operations inside containers via SSH key mounting
- Protect against accidental data loss with dirty check on clone deletion
- Allow SSH key assignment at repository creation and later modification

**Non-Goals:**
- Modifying existing tool type compose templates
- Installing git in containers (assumes tool images have git or install it)
- Multiple SSH keys per container
- Automatic push/pull/sync between host and container
- Shallow clones (full history only)

## Decisions

### 1. Host-Side Clone (not in-container)

**Decision**: Clone happens on the host before container start, not inside the container.

**Rationale**:
- No changes to compose templates required
- Works with all existing tool types immediately
- No need for git/SSH inside every container image
- Host has direct filesystem access to the clone
- Easier error handling and rollback

**Alternative considered**: In-container clone via command override. Rejected because it requires git in every image, SSH auth setup inside containers, and makes error handling fragile.

### 2. SSH Key Mounting via `_modify_compose_file`

**Decision**: Inject SSH key volume dynamically at container start time using the existing `_modify_compose_file` helper.

**Rationale**:
- Zero changes to tool type definitions
- Consistent with how other runtime overrides work (port, command, working_dir, extra_volumes)
- Mounts the `.ssh/` directory with key + config into container

**Implementation**:
```
instance_dir/.ssh/
  id_ed25519      (decrypted private key, mode 600)
  id_ed25519.pub  (public key)
  config          (StrictHostKeyChecking no)
```

Mounted as: `instance_dir/.ssh:/root/.ssh:ro` (or appropriate home dir)

### 3. Single SSH Key per Repository

**Decision**: The SSH key is stored on `GitRepository` and used for both clone and container access.

**Rationale**:
- Natural association: a repository's clone URL determines which SSH key is needed
- Simpler UX: one key per repo, not per session
- Session creation can override (future enhancement) but defaults to repo key

### 4. Dirty Check via `git status --short`

**Decision**: Check for uncommitted changes using `git status --short` before allowing deletion of clone-mode instances.

**Rationale**:
- Simple and reliable
- Catches staged, unstaged, and untracked files
- Fast (local filesystem operation)

## Risks / Trade-offs

**[Risk] Disk space usage** → Each clone-mode instance duplicates the full repository. Mitigation: Instance deletion removes the clone directory.

**[Risk] Clone time for large repos** → Synchronous clone during instance creation may timeout. Mitigation: No timeout on clone operation; consider async clone in future.

**[Risk] SSH key permissions in containers** → Some containers run as non-root users. The `.ssh` directory mount needs correct ownership. Mitigation: Mount as read-only; container's entrypoint may need to copy to writable location if needed.

**[Risk] Git not installed in custom tool images** → User-defined tool types may not have git. Mitigation: Document requirement; built-in types already have or install git.

**[Risk] SSH host key checking** → Cloning from new hosts may fail. Mitigation: SSH config sets `StrictHostKeyChecking no` for clone operations.

## Migration Plan

1. Run Alembic migrations to add new columns
2. Existing instances default to `clone_mode='mount'` (no behavior change)
3. Existing repositories have `ssh_key_id=null` (no behavior change until assigned)
4. No data migration needed

## Open Questions

- Should the `.ssh` mount be read-only or writable? (Writable needed if container generates new keys, but we don't support that)
- Should we support submodules in cloned repos?
