{"skill":{"slug":"quick-backup-restore","displayName":"Time Clawshine — OpenClaw Time Machine","summary":"Restic-powered encrypted time machine for OpenClaw: hourly incremental snapshots, fast restore by time/snapshot/file, local-only privacy defaults, integrity...","description":"---\nname: quick-backup-restore\ndescription: \"Restic-powered encrypted time machine for OpenClaw: hourly incremental snapshots, fast restore by time/snapshot/file, local-only privacy defaults, integrity checks, retention, and optional alerts. Setup can run with sudo, install dependencies, create systemd/cron persistence, restore over current files, and prune or purge recovery data.\"\nmetadata: { \"openclaw\": { \"emoji\": \"⏱\", \"requires\": { \"bins\": [\"bash\", \"openssl\", \"curl\", \"jq\"], \"auto_install\": [\"restic\", \"yq\"] }, \"install\": [{ \"id\": \"setup\", \"kind\": \"shell\", \"label\": \"Run Time Clawshine setup\", \"command\": \"sudo bash {baseDir}/bin/setup.sh\" }], \"homepage\": \"https://github.com/marzliak/quick-backup-restore\", \"capabilities\": { \"filesystem\": [\"read configured backup paths\", \"write encrypted restic repository\", \"restore snapshots to target paths\", \"forget/prune snapshots\", \"optional destructive purge\"], \"system\": [\"sudo setup\", \"optional package install\", \"optional systemd timer or cron\", \"optional logrotate and /usr/local/bin install\"], \"network\": [\"optional Telegram\", \"optional healthcheck\", \"optional ClawHub update check\", \"blocked by privacy.local_only by default\"], \"sensitive_data\": [\"OpenClaw memory\", \"sessions\", \"config\", \"user-added paths may contain secrets\"] } } }\n---\n\n# ⏱🦞 Time Clawshine — OpenClaw Time Machine\n\n**Your agent just nuked its own memory. Now what?**\n\nYou spent weeks training your OpenClaw agent — building memory, refining context, tuning personality. Then one bad session wipes it. Gone. And your last \"real\" backup? Yesterday. Maybe last week.\n\n**Time Clawshine gives OpenClaw a local encrypted time machine.** Every hour, restic takes an incremental snapshot of your agent's brain — memory, sessions, config, everything. Only changed bytes are stored, so backups stay fast and compact. When things break (and they will), you roll back by time, snapshot, or file to *exactly* the moment before it happened. Not yesterday. Not \"the last backup.\" The exact hour.\n\nSecurity note: this is a privileged backup/restore tool, not a narrow read-only helper. Setup can install packages and a scheduler with `sudo`; restore can overwrite current files; retention/prune can remove old recovery points; and optional external integrations can send minimal operational metadata only after explicit opt-in.\n\n**One command to install. Zero maintenance. Just works.**\n\n```bash\nsudo bash {baseDir}/bin/setup.sh\n```\n\n### Why this exists\n\n| Problem | Without Time Clawshine | With Time Clawshine |\n|---------|----------------------|---------------------|\n| Agent overwrites MEMORY.md | Hope you saved a copy | `restore.sh \"2h ago\"` |\n| Bad session corrupts context | Rebuild from scratch | Roll back one snapshot |\n| \"What changed?\" | No idea | `restic diff` between any two snapshots |\n| Disk fills up | Backup keeps growing | Dedup — only deltas stored |\n| Something fails | You find out next week | Local log, optional minimal Telegram ping |\n\n### What's under the hood\n\n- **Restic** — battle-tested backup engine, AES-256 encryption, incremental deduplication\n- **72 snapshots / 3 days** of history at hourly resolution (configurable)\n- **Disk guard** — aborts before filling your disk, optionally alerts via Telegram\n- **Integrity checks** — automatic `restic check` every 24 backups\n- **Daily digest** — Telegram summary with snapshot count, repo size, disk free\n- **Healthcheck ping** — opt-in healthchecks.io / hc-style endpoint pings (`/start`, `/`, `/fail`) so you also know when the backup *stops running*, not just when it fails\n- **Update awareness** — optional ClawHub check, disabled by default, never auto-updates\n- **Status dashboard** — `bin/status.sh` for a full health check at a glance\n- **Repository cleanup** — `bin/prune.sh` to manually reclaim disk space\n- **Self-test** — `bin/test.sh` validates backup→restore→verify roundtrip\n- **Guided setup** — agent reads `SETUP_GUIDE.md` and walks the user through every option\n- **Dry-run mode** — `backup.sh --dry-run` to validate without writing\n- **Uninstall** — `bin/uninstall.sh` for clean removal (preserves data by default)\n- **Local-only by default** — no Telegram, healthcheck, or update-check egress unless `privacy.local_only` is explicitly disabled\n\n---\n\n## Technical reference\n\n**Repository:** configured in `{baseDir}/config.yaml`\n**Log:** configured in `config.yaml` under `logging.file` (rotated weekly via logrotate)\n**Password file:** configured in `config.yaml` under `repository.password_file` (chmod 600 — **back this up separately**)\n\n---\n\n## When the user asks to set up or install Time Clawshine\n\n**First, read `{baseDir}/SETUP_GUIDE.md` and walk the user through each step interactively.** The guide covers Telegram, frequency, retention, extra paths, disk safety, and repo location. Configure `config.yaml` based on their answers before running setup.\n\nIf installing from ClawHub in OpenClaw, use the slug-only form:\n```bash\nopenclaw skills install quick-backup-restore\n```\nSome OpenClaw CLI versions reject owner-prefixed slugs such as `marzliak/quick-backup-restore`.\n\nIf the user wants a quick install without customization:\n\n1. Check if already set up:\n   ```bash\n   sudo bash {baseDir}/bin/status.sh\n   ```\n2. Run setup:\n   Preview first if the user wants to see dependencies, system files, and scheduler changes without modifying the machine:\n   ```bash\n   bash {baseDir}/bin/setup.sh --dry-run\n   ```\n   ```bash\n   sudo bash {baseDir}/bin/setup.sh\n   ```\n   For repo-only setup (no apt-get, no cron, no /usr/local/bin changes):\n   ```bash\n   sudo bash {baseDir}/bin/setup.sh --no-system-install\n   ```\n   For CI/automated setup (skip confirmation prompts):\n   ```bash\n   sudo bash {baseDir}/bin/setup.sh --assume-yes\n   ```\n3. Confirm setup succeeded:\n   ```bash\n   sudo bash {baseDir}/bin/status.sh\n   ```\n\n---\n\n## When the user asks to run a manual backup\n\n```bash\nsudo bash {baseDir}/bin/backup.sh\n```\n\nThen confirm with:\n```bash\nsudo bash {baseDir}/bin/status.sh\n```\n\n---\n\n## When the user asks to check backup status or history\n\nRun the status dashboard:\n```bash\nsudo bash {baseDir}/bin/status.sh\n```\n\nOr show the last 20 log lines:\n```bash\nsudo tail -20 \"$(yq e '.logging.file' {baseDir}/config.yaml)\"\n```\n\nList all snapshots (most recent first):\n```bash\nsudo bash {baseDir}/bin/restore.sh --help\n# Or directly:\nREPO=$(yq e '.repository.path' {baseDir}/config.yaml)\nPASS=$(yq e '.repository.password_file' {baseDir}/config.yaml)\nrestic -r \"$REPO\" --password-file \"$PASS\" snapshots\n```\n\nShow what changed between the two most recent snapshots:\n```bash\nREPO=$(yq e '.repository.path' {baseDir}/config.yaml)\nPASS=$(yq e '.repository.password_file' {baseDir}/config.yaml)\nSNAPS=$(restic -r \"$REPO\" --password-file \"$PASS\" snapshots --json | jq -r '.[-2:][].id')\nrestic -r \"$REPO\" --password-file \"$PASS\" diff $SNAPS\n```\n\n---\n\n## When the user asks to restore or roll back\n\n**Interactive restore (recommended — always dry-runs first):**\n```bash\nsudo bash {baseDir}/bin/restore.sh\n```\n\n**Restore by time (e.g. \"roll back 2 hours\"):**\n```bash\nsudo bash {baseDir}/bin/restore.sh \"2h ago\" --target /tmp/tc-restore\nsudo bash {baseDir}/bin/restore.sh yesterday --target /tmp/tc-restore\n```\n\n**Restore a specific file from the latest snapshot:**\n```bash\nsudo bash {baseDir}/bin/restore.sh latest --file /root/.openclaw/workspace/MEMORY.md --target /tmp/tc-restore\n# Preview the result, then move manually:\n# cp /tmp/tc-restore/root/.openclaw/workspace/MEMORY.md /root/.openclaw/workspace/MEMORY.md\n```\n\n**Restore a specific snapshot by ID:**\n```bash\nsudo bash {baseDir}/bin/restore.sh <snapshot_id>\n```\n\nAlways confirm with the user before executing a full restore to `/`.\nFor a restore targeting `/`, the script requires the exact confirmation phrase `RESTORE TO /`.\n\n---\n\n## When the user asks to check repo integrity\n\n```bash\nREPO=$(yq e '.repository.path' {baseDir}/config.yaml)\nPASS=$(yq e '.repository.password_file' {baseDir}/config.yaml)\nrestic -r \"$REPO\" --password-file \"$PASS\" check\n```\n\n---\n\n## When the user asks to change configuration\n\nEdit `{baseDir}/config.yaml` with the requested changes (schedule, retention, paths, Telegram credentials), then re-run setup to apply:\n```bash\nsudo bash {baseDir}/bin/setup.sh\n```\n\n---\n\n## When the user asks to customize backup paths\n\nRun the local path analyzer (100% offline — no API calls, no data leaves the machine):\n```bash\nsudo bash {baseDir}/bin/customize.sh\n```\n\nThis scans the system for:\n- Extra paths worth backing up (e.g. `~/.config`, custom scripts)\n- Common junk patterns to exclude (e.g. `node_modules`, `*.log`, `cache/`)\n\nShows suggestions and asks for confirmation before changing `config.yaml`.\nCredential stores such as `~/.ssh` and `~/.gnupg` are not auto-suggested. Add them only after explicit user approval and only when repository access and password-file backup are strongly controlled.\n\n---\n\n## When the user asks to clean up or free disk space\n\n```bash\nsudo bash {baseDir}/bin/prune.sh\n```\n\nOptions:\n- `--keep-last 24` — keep only last 24 snapshots\n- `--older-than 7d` — remove snapshots older than 7 days\n- `--dry-run` — preview what would be removed\n- `--yes` — skip confirmation prompt\n\n---\n\n## When the user asks to run a dry-run or test backup\n\n**Dry-run (validates without writing):**\n```bash\nsudo bash {baseDir}/bin/backup.sh --dry-run\n```\n\n**Self-test (full backup→restore→verify roundtrip in temp directory):**\n```bash\nbash {baseDir}/bin/test.sh\n```\n\n---\n\n## Important notes\n\n- **Silent by design:** cron/systemd runs every hour at :05 and logs to the configured log file. No output unless there is a failure.\n- **Telegram fires only on failure.** If the user has not configured `bot_token` and `chat_id`, failures are logged only.\n- **This is the time machine layer.** It protects against \"the agent broke something in the last 3 days.\" It is NOT a disaster recovery backup — that should be handled by an off-VM backup (e.g. restic to a remote server).\n- **Password:** The restic repository is AES-256 encrypted. The password file location is configured in `config.yaml` (chmod 600). Losing it means losing access to all snapshots.\n- **Never commit `secrets.env` or `.pass` files to git.** They are excluded via `.gitignore`.\n\n---\n\n## When the user asks to uninstall or remove Time Clawshine\n\n```bash\nsudo bash {baseDir}/bin/uninstall.sh\n```\n\nThis removes all system artifacts (systemd timer/service, cron, logrotate, binary, lock/marker files) but **preserves** the backup repository and password file.\n\nTo also delete all backup data (irreversible):\n```bash\nsudo bash {baseDir}/bin/uninstall.sh --purge\n```\n\nThe source files in the skill directory are never touched — can re-install with `sudo bin/setup.sh`.\n\n---\n\n## When the user asks to check for updates\n\nRun the status dashboard which includes update info:\n```bash\nsudo bash {baseDir}/bin/status.sh\n```\n\nOr check manually:\n```bash\nopenclaw skills update quick-backup-restore\n```\n\nNote: `backup.sh` automatically checks for updates once per day (if `updates.check: true` in config). It logs a warning when a new version is available but never updates automatically.\n","tags":{"backup":"3.2.3","disaster-recovery":"3.2.3","encrypted-backup":"3.2.3","latest":"3.2.3","local-backup":"3.2.3","openclaw":"3.2.3","privacy":"3.2.3","restic":"3.2.3","restore":"3.2.3","snapshots":"3.2.3","time-machine":"3.2.3","backup restore restic memory time-machine":"1.0.0","security":"3.2.0"},"stats":{"comments":0,"downloads":1302,"installsAllTime":1,"installsCurrent":1,"stars":1,"versions":21},"createdAt":1772754574722,"updatedAt":1780344697115},"latestVersion":{"version":"3.2.3","createdAt":1780344697115,"changelog":"Scheduler cadence hotfix: systemd installs now preserve simple custom cron schedules like 0 */2 * * * as matching OnCalendar values, and unsupported cron expressions fall back to cron.d instead of hourly. Docs also clarify OpenClaw slug-only install.","license":"MIT-0"},"metadata":{"setup":[],"os":null,"systems":null},"owner":{"handle":"marzliak","userId":"s17e8p1qmgndbnt8k67r1my2mh84hh5n","displayName":"Marz","image":"https://avatars.githubusercontent.com/u/5523806?v=4"},"moderation":null}