# R-649 — a failed install removes what it started (controller v0.266.0), 2026-09-23 **Operator ruling 2026-09-23:** "On failed install, the controller should clean up the containers." **Method: endpoint-level** on scratch guest 9202 (deploy through `POST /api/stacks//deploy`, state from `GET /api/stacks/`), drill catalog: `outline` with its redis healthcheck set to `false` in the DRILL template only, so `compose up -d` fails after postgres and redis have started. | proof | result | evidence | |---|---|---| | failed install | `deploy failed after 102.7s: exit code 1` → **`the failed deploy's containers were removed (volumes kept) — R-649`**; 0 containers of project `outline`; volumes `outline_outline_data`, `_postgres_data`, `_redis_data` kept; `deployed: false` | `20-*`, `21-*` | | the household's Remove afterwards | 200, volumes removed with the data | `30-*` | | floor | 0.266.0 / MinAgent 0.131.0 read back; demo-hp and demo-felhom on 0.266.0 in 20 s | `40-*` | Unit: `TestR649_AFailedInstallRemovesWhatItStarted` (stub compose; PATH = the stub only, R-650) and its control `TestR649_ASuccessfulInstallIsNotTakenDown`. Red-proof: the `down` removed → `calls=["up -d"]`. **Teardown:** outline removed through the product; `outlinewiki/outline:1.9.1` and controller 0.265.0 removed by name (postgres/redis images kept — in use by standing apps); `controller.yaml` identical to `.pre-r649`; live catalog `cfcfe52`; drill repo reset to live `main`. Host: nothing. Hub: floor only. 9201 not touched (reached 0.266.0 by the floor).