Repository navigation
Drift deploy v0.1.46
v0.1.46
Image-only release. Device deletion is now soft — the schema already supported it, but the delete code path was issuing a hard DELETE FROM devices, leaving zero trace + cascading away deployment_targets and terminal_sessions history.
Why
Caught when a gpu-machine device went missing and pg_stat_user_tables.n_tup_del was the only evidence anything had happened. log_statement = none (Postgres default) means individual DML doesn't hit the logs; combined with ON DELETE CASCADE on the FK tables, a hard delete is invisible after the fact. The devices table's partial unique index — UNIQUE(LOWER(name)) WHERE status::text <> 'removed'::text — was already designed for soft-delete tombstones with name-reuse, but routes_admin.delete_device was bypassing it.
What changed
DELETE /api/deploy/devices/{name}setsstatus = 'removed'instead of issuing a real DELETE.terminal_sessionsanddeployment_targetsFKs stay valid (no cascade), preserving the audit chain.GET /api/deploy/devicesfilters outstatus = 'removed'rows so tombstones don't appear in the UI / chat tool listings.authenticate_devicerejects removed devices with the same 401 it gives for not-found / no-token. The bootstrap token hash is preserved on the row (so the device can be restored), but check-ins are refused until an operator-sideUPDATEflips status back to a live state. Same 401 shape across all three cases — no information leak about whether a name was ever used./agent/bundles/{filename}excludes removed devices from the token-match scan, so a tombstoned device's preserved token can't fetch bundles either.
Recovery
If you need to bring back a soft-deleted device (mistakenly run DELETE, or restoring after gpu-machine-style accidental cleanup):
UPDATE devices SET status = 'online', last_seen = NULL
WHERE LOWER(name) = LOWER('<device-name>') AND status = 'removed';The bootstrap token hash on the row stays valid, so the existing edge-agent install on the device just resumes check-ins on its next tick. No re-commissioning needed.
To re-commission under the same name instead (fresh token, fresh fingerprint), the tombstone doesn't block — the partial unique index allows a new pending row to coexist with the old removed one. The POST /devices route already handles this case.
Operator action
Apply via the Software Updates modal in the UI (one-click). Image-only — no install.sh re-run, no edge agent change.
Migration / breaking changes
None for callers. The DELETE endpoint still returns 204 No Content. Existing hard-deleted devices (from before this release) are gone forever — soft-delete only protects deletions issued after v0.1.46 lands.