{"id":84844,"plugin_id":"plugin_asdk_app_6ad87c5571148191a56673a04a39d2ec","kind":"skill","collection_source":"plugin_package","comparison_source":null,"observed_at":"2026-11-06T18:21:07.521Z","digest":"376c3a1e539b488532cdec86baf7eaeebe5d785030f501f26ab4426b426586f0","against":null,"payload":{"description":"Take a locked SafeGrd backup of a database and prove it restores before a migration, a schema change, a bulk delete, a reset or any command that can lose data. Use when the user is about to change a production or staging database, or asks whether they have a recent backup that restores.","included_files":[],"name":"backup-before-risky-change","skill_md_contents":"---\nname: backup-before-risky-change\ndescription: Take a locked SafeGrd backup of a database and prove it restores before a migration, a schema change, a bulk delete, a reset or any command that can lose data. Use when the user is about to change a production or staging database, or asks whether they have a recent backup that restores.\n---\n\n# Back up, and prove it restores, before a risky change\n\nA backup that has not been restored is a guess. Before the change, get a snapshot taken\nafter the last write that matters, locked so nothing can delete it, and a Fire Drill that\nrestored it. Do not run the risky command until that is done, or until the user says to go\nahead without it.\n\n## 1. Find the surface\n\n1. Call `list_organizations`, then `list_surfaces`. A surface is one database, file tree\n   or mailbox. Match the user's database by `name`, `database_name` and `surface_type`.\n2. If more than one matches, ask which one. Two databases of the same engine are common\n   (production and staging, or MySQL and MariaDB).\n\n## 2. Read where it stands\n\n- `get_surface`: `last_backup_at`, `last_verified_at`, `last_heartbeat`, `schedule`.\n- `list_snapshots` with `limit: 1`: the newest snapshot, its `status`, and\n  `worm_retention_until` (locked until). A snapshot with `worm_mode` `NONE` is not locked.\n- `list_drills` with `limit: 1`: the newest Fire Drill, its `status` and the snapshot it\n  restored.\n\nTell the user what you found in a few lines before you ask for anything.\n\n## 3. Take a fresh backup\n\nChoose the first that applies:\n\n- **The SafeGrd CLI is on this machine and the surface is in its config** (`safegrd daemon\n  status` lists its id): run `safegrd guard --surface <id> -- <the risky command>`. It\n  backs up, checks the snapshot is locked, and only then runs the command. A refusal exits\n  3 and says why.\n  Use `safegrd backup --surface <id>` instead when the user wants the backup now and the\n  change later.\n- **Otherwise:** call `request_backup` with the surface's `node_id`, and read the answer:\n  - Accepted: the host's daemon runs it at its next check-in, or SafeGrd queues it for a\n    surface SafeGrd backs up. Call `list_snapshots` with `limit: 1` about once a minute\n    until a snapshot newer than the request appears. A request is not a backup.\n  - `HTTP 409`, no daemon on the host: nothing will pick the request up. Ask the user to\n    run `safegrd backup --surface <id>` on that host, then continue from step 4.\n  - `HTTP 429`: a backup was taken less than an hour ago. Each one is locked and stored\n    until it expires, so requests are at most hourly. Tell the user when it was taken, and\n    ask whether anything written since then matters.\n\n## 4. Prove it restores\n\nCall `request_drill` with the same `node_id`, then `list_drills` with `limit: 1` about once\na minute until a drill of the new snapshot appears.\n\n- `passed`: report the assertions it checked (tables and rows restored, digests).\n- `failed`: stop. Report the failing assertion and tell the user not to proceed.\n- `HTTP 429`: the plan's drill cadence is used up until the time the answer gives. Report\n  the newest passed drill and which snapshot it restored, and say the new snapshot is not\n  yet proven.\n\n## 5. Report\n\nOne fact per line: the surface, the snapshot id, when it was taken, locked until when, and\nthe drill result. Then say whether it is safe to proceed. Anything written after the\nsnapshot is not in it, so the user should pause writes or accept losing them.\n"},"changes":[],"summary":"First saved snapshot. No earlier version is available for comparison.","summary_kind":"deterministic","summary_metadata":{}}