# Tasks — BooControl SSH editor verb-mode + model pull ## T1 — schema - [x] `apps/control/src/schema.sql`: `ALTER TABLE control_hosts ADD COLUMN IF NOT EXISTS ssh_mode TEXT NOT NULL DEFAULT 'shell'`. Verify: `pnpm -C apps/control build`. ## T2 — RemoteOps seam (shell + wrapper) - [x] In `ssh-config.ts` add the `RemoteOps` interface + `shellOps(target, configPath, exec)` (current command strings) + `wrapperOps(target, exec)` (verbs `read`/`backup`/`write`/`restart`). Verify: existing `ssh-config.test.ts` still green. ## T3 — thread mode through the pipeline - [x] `readRemoteConfig` and `applyRemoteConfig` accept `mode: 'shell'|'wrapper'` (default `'shell'`) and select ops. `applyRemoteConfig` backup uses the ops' returned path. Verify: `pnpm -C apps/control test` (ssh-config shell-mode unchanged). ## T4 — wrapper-mode tests - [x] Add tests: wrapper ops emit `read`/`backup`/`write`(stdin)/`restart` verbs; `applyRemoteConfig({mode:'wrapper'})` reads the backup path from the `backup` verb's stdout; failure at each step reported. Verify: `pnpm -C apps/control test`. ## T5 — model pull job - [x] `services/model-pull.ts`: `runModelPull` with server-side repo-id validation, wrapper `pull ` verb (shell fallback using a `models_dir`), `control_job` (jobType `action`, `detail.kind='pull'`) progress. Verify: `model-pull.test.ts` (validation accept/reject + verb emission). ## T6 — routes - [x] `routes/ssh-config.ts`: accept `sshMode` in `PATCH /api/hosts/:id`; pass each host's `ssh_mode` into read/diff/apply; add `POST /api/hosts/:id/pull {repo}` (202, non-blocking). Verify: `pnpm -C apps/control build`. ## T7 — UI - [x] `HostConfigEditor.tsx`: SSH-mode selector (`shell`/`wrapper`) in the settings form; a "Pull model" repo input + button that POSTs and surfaces job status. Verify: `npx tsc -p apps/web/tsconfig.app.json --noEmit`. ## T8 — gates - [x] Full gates: control build + test, web tsc. Verify each command above passes. ## Deferred (YAGNI) - Dedicated `control_job` jobType `pull` (reuse `action`). Reopen trigger: pull needs distinct UI filtering from other actions. - `huggingface-cli` progress-percent parsing. Reopen trigger: operators want a progress bar rather than streamed lines.