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-backupproduct 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
- Captura declarativa do ambiente do usuário num manifesto
.kvgassinado, armazenado em
kdrive://users/<user>/snapshots/. - Restauração one-click via Koder ID login, integrada ao
kodix-installer-gui. - Reutilização do mesmo manifesto em ≥3 surfaces: Settings UI, CLI,
Installer.
- 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-002futuro. - Versionamento system-level (rollback de kernel etc —
apt-historyresolve).
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 timerMulti-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>/shareendpoint creates ACL entry. Default = private.
Hyperscale considerations (per policies/hyperscale-first.kmd)
- Delta snapshots: each snapshot has optional
parent. Restore walkschain from leaf to root, applying patches.
- Content-dedup: data blobs stored by
sha256(content), manifestreferences hash. Multiple snapshots sharing
~/Documentos(unchanged) reuse the same blob. - Repo bundles dedup:
saude-publicabundle for snapshot N+1 canreference 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:
koder-settings→ aba "Backup" usaKoderSnapshotPickerwidgetkodix-installer-gui→ wizard step usaKoderSnapshotPickerkoder-snapshot/koder-restoreCLI → wrapper around sharedkoder_snapshot.dartlib 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
.mdperpolicies/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
- This RFC: