RFC: Koder Snapshot/Backup — declarative environment capture/restore

  • Status: Draft v2 (2026-05-21)
  • Authors: Rodrigo (owner) + claude-opus-4-7 (drafting)
  • Primary component: products/horizontal/backup/ (new sector — Android-style cross-platform Backup app)
  • Backend components: services/foundation/id (snapshot service), products/horizontal/drive (storage namespace)
  • Surface components: engines/sdk/koder_kit (auththeme widgets), `infralinuxkodix (preinstall + welcome), coresettings` (deep-link)
  • Tracking: snapshots-RFC-001
  • Supersedes: none
  • Revisions:
    • v1 (2026-05-21): Initial design — snapshot integrated into installer-gui + Settings tab + koder-tools CLIs as standalone tools.
    • v2 (2026-05-21): Major redesign — spun off as dedicated koder-backup product module (RFC-006 sector) with 5 canonical surface variants (desktopmobilecliwebtv). Mirrors Android/iOS native backup app model. Installer and Settings become thin integration points (deep-links).

Problem

Recriar o ambiente Koder Kodix após formatação / reinstalação / migração pra máquina nova requer hoje passos manuais ad-hoc: backup tar.gz pro Drive, push de repos sem origin (saude-publica), koder-stack re-clone, /k-setup local re-link, rclone config re-auth, gnome-keyring re-import, reinstalar apps via aptsnapflatpak/kpkg.

Não há manifesto declarativo do que constitui o ambiente do usuário, nem autenticação Koder ID pra parear o backup ao usuário, nem integração no installer GUI pra restauração one-click.

Goals

  1. Captura declarativa do ambiente do usuário num manifesto .kvg

    assinado, armazenado em kdrive://users/<user>/snapshots/.

  2. Restauração one-click via Koder ID login, integrada ao

    kodix-installer-gui.

  3. Reutilização do mesmo manifesto em ≥3 surfaces: Settings UI, CLI,

    Installer.

  4. Multi-tenant, self-hosted, hyperscale-first.

Non-goals

  • Backup de dados brutos do filesystem (já coberto por /k-backup).
  • Sincronização contínua (Time Machine / OneDrive style). Ver

    snapshots-RFC-002 futuro.

  • Versionamento system-level (rollback de kernel etc — apt-history

    resolve).

Architecture

Manifest schema (KVG)

[snapshot]
version       = 1
hostname      = "<host>"
created_at    = "<RFC3339>"
koder_user_id = "<user>"
parent        = "<previous-snapshot-id>"   # null for full
sig.ed25519   = "<base64 over canonical bytes>"

[system]
timezone   = "..."
locale     = "..."
keyboard   = "..."
gpu_driver = "..."   # nullable; restore checks compat

[apps]
apt     = ["pkg", ...]
snap    = [{name, channel}]
flatpak = [{ref, origin}]
kpkg    = ["slug", ...]

[[repos.entry]]
slug   = "..."
url    = "https://flow.koder.dev/... | kdrive://users/.../bundles/X.bundle"
path   = "~/dev/..."
branch = "..."

[secrets]            # selectively-encrypted with user's Koder ID pubkey
ssh_id_ed25519       = "<base64-encrypted>"
netrc                = "..."
gpg_secring          = "..."
rclone_config        = "..."
gnome_keyring_export = "..."

[[files.entry]]
local_path = "~/Documentos"
blob       = "kdrive://users/.../snapshots/<id>/data/Documentos.tar.zst"
sha256     = "..."

[skips]
patterns = ["~/.cache
.git for repos (URL + branch + dirty check)
  │   ├─ dpkg-query --show explicit-installed → apt list
  │   ├─ snap list, flatpak list, kpkg list
  │   ├─ gsettings list-recursively → system block (filtered)
  │   ├─ Read .ssh, .gnupg, .netrc, .config/rclone, .local/share/keyrings
  │   ├─ Encrypt secrets with user pubkey
  │   ├─ Tar Documentos/Imagens/Vídeos/Downloads (filtered) → data blobs
  │   ├─ Generate manifest.kvg
  │   ├─ Sign with Ed25519 identity privkey
  │   └─ POST /v1/me/snapshots (multipart: manifest + blobs)
  │
  └─ Toggle "Snapshot automático semanal" → systemd timer

Multi-tenancy contract (per specs/multi-tenancy/contract.kmd)

  • All Drive paths under users/<user_id>/. ACL via kdrive RLS.
  • Cross-tenant read → 404 (not 403, per spec).
  • Snapshot share between users: explicit POST /v1/snapshots/<id>/share

    endpoint creates ACL entry. Default = private.

Hyperscale considerations (per policies/hyperscale-first.kmd)

  • Delta snapshots: each snapshot has optional parent. Restore walks

    chain from leaf to root, applying patches.

  • Content-dedup: data blobs stored by sha256(content), manifest

    references hash. Multiple snapshots sharing ~/Documentos (unchanged) reuse the same blob.

  • Repo bundles dedup: saude-publica bundle for snapshot N+1 can

    reference snapshot N's bundle if HEAD unchanged.

  • Compression: zstd level 19 on data blobs, zstd-22 on manifest.

Security (per policies/security.kmd + policies/identity-data-retention.kmd)

  • TLS-only to koder-id, koder-drive endpoints.
  • Secrets never leave user's machine unencrypted.
  • Manifest sig validation mandatory on restore (refuse unsigned or

    invalid).

  • Audit log on every snapshot create/access (per

    services/foundation/id/engine/services/audit/).

  • Retention: snapshots kept indefinitely by default; user can delete

    any. On DELETE /v1/me (LGPD erasure), cascade-delete all user's snapshots within 24h grace window.

Reuse-first compliance (per policies/reuse-first.kmd)

Three consumers minimum:

  1. koder-settings → aba "Backup" usa KoderSnapshotPicker widget
  2. kodix-installer-gui → wizard step usa KoderSnapshotPicker
  3. koder-snapshot / koder-restore CLI → wrapper around shared

    koder_snapshot.dart lib in koder_kit

Same lib used by all 3. No duplication.

Self-hosted compliance (per policies/self-hosted-first.kmd)

  • Storage: koder-drive (gate G2 passed per registries/self-hosted-pairs.md).
  • Auth: koder-id (gate G2 passed).
  • Encryption: libsodium (open-source, no external service).
  • Zero dependency on Google Drive, GitHub, Dropbox, iCloud.

Spec migration

  • All artifacts use .kvg (Koder Value Graph) or .kmd (this RFC).
  • No .md per policies/document-format.kmd.
  • Spec location follows policies/content-location.kmd:
    • This RFC: meta/docs/stack/rfcs/snapshots-RFC-001-architecture.kmd
    • Manifest spec: meta/docs/stack/specs/snapshots/manifest.kmd
    • Per-component policies: each component's `policies