# L9 — Remote (SSH + WSL)

**Binôme :** `dev-remote` / `test-remote`
**Zones :** `infrastructure/remote`, `application/remote`, `frontend/features/remote`
**Dépendances amont :** L0, L1, L2, L3, L8.

## Objectif
Développement distant : projet sur autre machine via **SSH**, ou sur une **WSL** depuis Windows. Transparence local/distant via la stratégie `RemoteHost`.

## Périmètre (DEV)
- `RemoteHost` : `LocalHost`, `SshHost` (russh/ssh2), `WslHost` (`wsl.exe`) — fabriquent FS/PTY/Spawner adaptés.
- Adapters distants : `SshFileSystem` (SFTP), `SshPtyAdapter`, `SshProcessSpawner` ; `WslFileSystem`, `WslPtyAdapter`, `WslProcessSpawner`.
- `RemoteGitRepository` (git CLI via `ProcessSpawner`) en fallback distant.
- Use case `ConnectRemote` (valide l'accès au root). Front : UI de connexion SSH/WSL.

## Périmètre (TEST)
- Substituabilité (Liskov) : un use case marche identiquement quel que soit le `RemoteHost` (tests avec hosts mockés).
- Intégration SSH/WSL : tests `#[ignore]` gated derrière feature/env (CI conditionnelle).
- Front : feature remote avec gateway mock.

## Definition of Done
- `cargo test` (remote, hors `#[ignore]`) + `vitest` verts ; connexion SSH et WSL démontrée en dev manuel.

## Avancement

### ✅ Socle (vert)
- **Domaine** : `RemoteRef` (Local/Ssh/Wsl) + port `RemoteHost` (fabrique FS/PTY/Spawner) déjà en place (L0).
- **Infra** (`infrastructure/remote/mod.rs`) : `LocalHost` (fabrique les adapters locaux ; `connect` = no-op) + sélecteur `remote_host(&RemoteRef)` (Local → `LocalHost` ; SSH/WSL → `RemoteError::Connection` explicite « not yet supported »). 4 tests d'intégration.
- **Application** (`application/remote/`) : `ConnectRemote` (établit l'hôte, valide que le root existe via le FS de l'hôte, émet `RemoteConnected`). 3 tests **Liskov** (comportement identique Local/Ssh/Wsl avec hôte mocké ; échec connexion → REMOTE ; root absent → NOT_FOUND).
- `cargo test --workspace` : **317 verts, 0 régression** ; clippy clean.

### ⏳ Reste à faire (gated / non vérifiable dans cet environnement)
- Adapters distants **SSH** (`SshHost`/`SshFileSystem` SFTP/`SshPtyAdapter`/`SshProcessSpawner` via russh ou ssh2 — décision auth à figer, cf. spikes) et **WSL** (`WslHost` + adapters préfixant `wsl.exe`), avec tests d'intégration `#[ignore]` derrière feature/env.
- `RemoteGitRepository` (git CLI distant via `ProcessSpawner`) + `pull`/`push` (reportés depuis L8).
- IPC `app-tauri` `connect_remote` + front feature remote (UI connexion SSH/WSL).

## Spikes (cf. ARCHITECTURE §13)
- Auth SSH (clé/agent/mot de passe/known_hosts) ; choix russh(rustls) vs ssh2(OpenSSL) — impacte l'AppImage.
- Conversion de chemins WSL `/mnt/...` ↔ `\\wsl$\...` ; perf I/O cross-boundary.
- Git sur FS distant (perf, parsing CLI).
