<!-- skill: WordPress Maintenance | version: 1.0.0 | description: Secure WP upkeep — staging, backups, migrations and cleanup | category: Web -->

## Instructions
- Golden rule: never update or migrate production without a verified full backup (files + database) you have actually test-restored once.
- Staging first: clone to `staging.` subdomain (push-button host clone or Duplicator), run all updates/tests there, then replicate to live.
- Update order: staging → full backup → core → theme (child-theme safe) → Woo/plugins → retest critical flows (login, forms, checkout, menus).
- Backup scope: `wp-content/` + `wp-config.php` + `.htaccess` + full DB dump (`wp db export`); store 3 copies (server + offsite S3/Drive + local), retain 30 days.
- Restore drill: files back → `wp db import` → `wp search-replace` URLs if host changed → flush cache + permalinks → verify admin + front end.
- Migration with search-replace: use `wp search-replace 'old.test' 'new.com' --all-tables --dry-run` first, then run for real; never hand-edit SQL dumps for URLs.
- WP-CLI is primary: `wp core/plugin/theme update`, `wp db optimize`, `wp transient delete --all`, `wp rewrite flush`; avoid dashboard bulk-updates on big sites.
- Security baseline: unique admin user (never `admin`), 2FA + limit-login-attempts, file perms 644/755 (`wp-config.php` 600), disable file editing (`DISALLOW_FILE_EDIT`).
- Hacked-site cleanup: take offline → backup evidence → scan (Wordfence/Sucuri) → reinstall core + fresh plugin copies → reset all passwords/salts → remove unknown admins/crons.
- Performance: cache plugin (host-aware), image WebP + ≤200KB, keep plugins <25, remove inactive themes/plugins, schedule `wp cron` via real cron on traffic sites.
- Monitor: uptime check, `WP_DEBUG_LOG` reviewed weekly, disk + backup-success alerts, broken-link + 404 review monthly.
- Document: keep `site-runbook.md` (host, PHP version, backup location, update order, rollback steps) next to the site so any agent can recover it.

## Examples
- Monthly care run: staging clone → backup verify → core/theme/plugin updates → visual + checkout regression → backup anew → changelog note.
- Host migration: Duplicator package from shared host → import on VPS → `wp search-replace` domain → SSL + permalinks + cache flush → DNS cutover at low traffic.
- Hack recovery: Sucuri scan flags timthumb backdoor → maintenance mode → fresh core/plugins → `wp user reset-password` all → new salts → Google Search Console review request.

## Workflows
1. Pre-flight: note versions (`wp core/plugin/theme list`), full backup (files+DB), verify backup size + SQL head.
2. Stage + update: clone to staging, update in order core→theme→plugins, fix conflicts there, screenshot key pages.
3. Cutover: maintenance window, backup live once more, replay proven updates, `wp cache flush && wp rewrite flush`.
4. Migrate (if moving): package/transfer → import → `search-replace --dry-run` → live run → SSL/permalinks/cache → DNS.
5. Harden + hand off: 2FA/perms/cron verified, backup schedule green, runbook updated, uptime monitor armed.

## Templates
```bash
# Full backup + update sequence (run from site root)
wp db export ~/backups/$(date +%F)-db.sql
tar -czf ~/backups/$(date +%F)-files.tgz wp-content wp-config.php .htaccess
wp core check-update && wp plugin list --update=available
wp core update && wp theme update --all && wp plugin update --all
wp transient delete --all && wp rewrite flush && wp cache flush
wp core version && wp plugin list --update=available
```
```bash
# Migration search-replace + cleanup helpers
wp search-replace 'https://old.example.com' 'https://new.example.com' --all-tables --dry-run
wp search-replace 'https://old.example.com' 'https://new.example.com' --all-tables
wp users list --role=administrator
wp config set DISALLOW_FILE_EDIT true --raw
```

## Tools
- SARAH `shell_run`: all `wp ...` commands above; `tar`/`mysqldump` for backups when WP-CLI DB fails.
- SARAH `file_write`: edit only `wp-config.php` snippets, child-theme files, and `site-runbook.md`; never core/plugin files.
- SARAH preview: after updates load homepage + wp-admin + one form/checkout; confirm no PHP fatals in `wp-content/debug.log`.

## Advanced
- Rollback: keep prior backup pair labeled; files restore via `tar -xzf`, DB via `wp db import`; if white-screened, rename `plugins/` to `plugins-off` to isolate culprit.
- Troubleshooting: WSOD → enable `WP_DEBUG_LOG` + check `debug.log`; 500 after migrate → `.htaccess`/PHP version/perms; mixed-content → missed `http→https` search-replace on `postmeta`.
- Cron: on real traffic define `DISABLE_WP_CRON=true` + `* * * * * wp cron event run --due-only` via system cron.
- Pro tips: `wp db optimize`, `wp media regenerate` after theme change, `wp option get home/siteurl` to confirm canonical URLs before DNS flip.

## Documentation
- WP-CLI handbook: https://developer.wordpress.org/cli/commands
- Hardening WP: https://wordpress.org/documentation/article/hardening-wordpress
- WP backups: https://wordpress.org/documentation/article/wordpress-backups
