Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Set up Convex backups and run a restore DRILL that proves recovery — snapshot, restore into a throwaway preview, assert the data came back — plus a schedule matched to your RPO and a gated recovery runbook.
.claude/skills/get-convex-convex-backup/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-05 | ✗→✓ | ▲ Improved | 131% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 79% | 0% |
| case-08 | ✗→✓ | ▲ Improved | -35% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 9% | 0% |
| case-11 | ✗→✓ | ▲ Improved | -4% | 0% |
<!-- GENERATED from convex-agents content/capabilities/convex-backup.json — do not edit by hand. -->
Every backup story has two halves and most people only do the first: taking the backup, and proving you can get it back. This capability does both — it sets up regular snapshot exports and then runs a RESTORE DRILL that actually recovers the data into a disposable preview and asserts it's intact. The drill reuses migrate-rehearse's exact primitives (snapshot export → preview deploy → snapshot import) pointed at recovery instead of a forward change, so the safety net is tested, not assumed.
npx convex export --path backup-<date>.zip (add --include-file-storage if the app stores files). This is the backup artifact; treat it as sensitive real data.npx convex export via CI/cron to durable storage the user controls, with a retention window. Convex's own platform backups exist; this adds a user-owned, portable copy.(a) PRECONDITION: a Preview Deploy Key as CONVEX_DEPLOY_KEY (same requirement as migrate-rehearse; a paid-tier feature). If unavailable, drill against a fresh personal dev deployment instead and say so. (b) create a throwaway preview from the CURRENT code: npx convex deploy --preview-create restore-drill-<date>. (c) restore the snapshot into it: npx convex import backup-<date>.zip --deployment restore-drill-<date> --replace (import targets a deployment by NAME with --deployment; there is no --preview-name on import). (d) ASSERT recovery: read the restored data back (MCP tables for row counts, data/runOneoffQuery for spot-checks) and confirm the critical tables came back with the expected row counts and a sample of real records — a restore that 'succeeds' but lands 0 rows is a FAILED drill. Compare against the source's counts where available.
npx convex import backup.zip --replace --prod, gated by deploy-guard, with the post-snapshot-write-loss caveat stated).| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-05 | fail→pass | 17,015 | 30,253 | +78% | 1 | 1 | 0% | 2,424 | 5,591 | +131% | 0 | 0 | — |
case-01 | fail→fail | 25,330 | 16,448 | -35% | 1 | 1 | 0% | 3,824 | 1,501 | -61% | 0 | 0 | — |
case-02 | fail→fail | 17,692 | 5,759 | -67% | 1 | 1 | 0% | 3,425 | 1,440 | -58% | 0 | 0 | — |
case-03 | fail→fail | 28,142 | 5,314 | -81% | 1 | 1 | 0% | 4,029 | 1,302 | -68% | 0 | 0 | — |
case-04 | fail→fail | 9,620 | 19,681 | +105% | 1 | 1 | 0% | 1,777 | 3,985 | +124% | 0 | 0 | — |
case-06 | fail→fail | 12,070 | 22,144 | +83% | 1 | 1 | 0% | 2,035 | 4,153 | +104% | 0 | 0 | — |
case-07 | fail→pass | 8,169 | 7,652 | -6% | 1 | 1 | 0% | 1,135 | 2,029 | +79% | 0 | 0 | — |
case-08 | fail→pass | 17,821 | 4,768 | -73% | 1 | 1 | 0% | 2,672 | 1,744 | -35% | 0 | 0 | — |
case-09 | fail→pass | 17,300 | 9,204 | -47% | 1 | 1 | 0% | 2,306 | 2,503 | +9% | 0 | 0 | — |
case-10 | pass→pass | 11,266 | 8,193 | -27% | 1 | 1 | 0% | 1,699 | 2,060 | +21% | 0 | 0 | — |
case-11 | fail→pass | 12,285 | 6,149 | -50% | 1 | 1 | 0% | 1,937 | 1,856 | -4% | 0 | 0 | — |
case-12 | pass→pass | 11,152 | 6,899 | -38% | 1 | 1 | 0% | 1,548 | 1,834 | +18% | 0 | 0 | — |
case-13 | pass→pass | 18,087 | 10,801 | -40% | 1 | 1 | 0% | 2,751 | 2,359 | -14% | 0 | 0 | — |
case-14 | pass→pass | 19,770 | 13,986 | -29% | 1 | 1 | 0% | 2,463 | 3,131 | +27% | 0 | 0 | — |
case-15 | fail→pass | 14,892 | 7,694 | -48% | 1 | 1 | 0% | 2,189 | 2,134 | -3% | 0 | 0 | — |
case-16 | pass→pass | 10,431 | 7,940 | -24% | 1 | 1 | 0% | 1,511 | 2,151 | +42% | 0 | 0 | — |
case-17 | fail→pass | 10,833 | 6,343 | -41% | 1 | 1 | 0% | 1,637 | 1,852 | +13% | 0 | 0 | — |
case-18 | pass→pass | 16,137 | 6,975 | -57% | 1 | 1 | 0% | 2,159 | 2,014 | -7% | 0 | 0 | — |
case-19 | fail→pass | 14,455 | 3,262 | -77% | 1 | 1 | 0% | 1,892 | 1,478 | -22% | 0 | 0 | — |
case-20 | pass→pass | 13,621 | 7,785 | -43% | 1 | 1 | 0% | 1,893 | 1,899 | +0% | 0 | 0 | — |
case-21 | pass→pass | 6,313 | 6,993 | +11% | 1 | 1 | 0% | 915 | 1,799 | +97% | 0 | 0 | — |
case-22 | pass→pass | 27,357 | 23,876 | -13% | 1 | 1 | 0% | 4,048 | 4,407 | +9% | 0 | 0 | — |
case-23 | fail→pass | 11,393 | 4,647 | -59% | 1 | 1 | 0% | 1,496 | 1,561 | +4% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted, and 20 counted toward the lift figure. The other 3 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +39 percentage points is the difference between those two pass rates over the 20 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.