# Recovering Lost Code from a Destroyed Sprite ## What happened During a migration of precis.fyi from a sprite (ephemeral dev environment) to Fly.io, Claude Code completed all the work — writing deployment config, modifying application code, deploying successfully — but the sprite was destroyed before the changes were committed and pushed to GitHub. The repo at `medecau/precis-fyi` still contained the pre-migration state. ## What was lost Three new files and three targeted changes to `main.py`: - `Dockerfile`, `fly.toml`, `.dockerignore` — never existed in the repo - `main.py`: database path made configurable via `DATA_DIR` env var, DBOS system database pointed to the persistent volume, SQLite WAL mode enabled ## Recovery approach The key insight was that the **deployed application was still running**. Rather than reconstruct from the migration report (which had good high-level detail but lacked exact code), we: 1. Installed `flyctl` and authenticated to Fly.io 2. SSHed into the running `precis-fyi` machine and pulled `/app/main.py` directly 3. Ran `diff` against the repo version — yielded a clean, 3-hunk diff with no ambiguity 4. Retrieved the exact app configuration via `fly config show` for `fly.toml` 5. Identified the process entrypoint (`uv run python main.py`) from `/proc/*/cmdline` on the machine 6. Reconstructed `Dockerfile` and `.dockerignore` from report details + the process evidence 7. Verified the Dockerfile with `fly deploy --build-only` before committing ## What made this possible - The production machine was still running — the deployed code is the ground truth - `fly config show` outputs the canonical app configuration in parseable JSON - The migration report accurately described the architecture (trixie base image, WAL mode, DATA_DIR pattern, DBOS system_database_url) even if it didn't have exact code ## Lesson When doing migration work on a sprite, create a checkpoint (`sprite-env checkpoints create`) or commit incrementally as each piece is done — especially before destroying the environment. Alternatively, push a WIP branch; even an incomplete commit preserves the work.