Skip to content

Full GenHub System Backup, Export & Disaster Recovery (CAS Pool, Manifests, Profiles & State) #387

Description

@undead2146

[Feature] Full GenHub System Backup, Export & Disaster Recovery (CAS Pool, Manifests, Profiles & State)

1. Problem Statement & Context

GenHub's content architecture separates configuration from binary assets:

  • Game Profiles & Settings: %LOCALAPPDATA%\GenHub\Profiles\ and %LOCALAPPDATA%\GenHub\settings.json
  • Manifest Pool: %LOCALAPPDATA%\GenHub\Manifests\
  • Content-Addressable Storage (CAS) Pool: %APPDATA%\Roaming\GenHub\cas-pool\ and drive-adjacent .genhub-workspace\cas-pool\
  • Application State & Preferences: User configuration, tool installations, and launcher mappings.

When a user performs a clean uninstallation (or migrates to a new system/drive), Velopack completely wipes %LOCALAPPDATA%\GenHub.

The Critical CAS Dependency Problem

A GameProfile is only an abstract configuration recipe referencing ManifestIds and content entries. It does not contain game binaries, DLLs, or BIG files. If the CAS object store or Manifest Pool is wiped or missing:

  • Restoring only gameprofiles.json yields unlaunchable profiles because there are no physical CAS blobs to hard-link into the game directory.
  • For complete disaster recovery, an offline backup must package Profiles, Manifests, User Settings, and CAS Object Blobs into a single, deduplicated archive (.ghbak).

(Note: Standalone Profile Sharing—where missing CAS objects are dynamically re-downloaded via remote acquisition resolvers—will be tracked in a separate future issue).


Architectural Clarification: Disaster Recovery vs. GameProfile Sharing

Dimension Full System Backup & Disaster Recovery (This Issue) GameProfile Sharing / Bundles (Future Feature)
Scope Complete system snapshot or selected offline profile bundle. Lightweight profile definition + manifest references.
CAS Content Includes all underlying CAS blobs required to reconstruct files offline. Excludes binary blobs; contains only hashes and acquisition URLs.
Target Use Case Cold storage backup, PC migration, offline recovery, zero-dependency restore. Community modpack sharing, exporting configuration to friends.
Network Requirement 100% Offline / Air-gapped restore capability. Requires online acquisition resolvers to fetch missing CAS blobs.
Size Gigabytes (contains full mod assets, game client binaries, tools). Kilobytes to Megabytes (pure metadata and manifests).

2. User Stories & Use Cases

  • UC-1 (Full Disaster Recovery): As a user upgrading or wiping my OS/drive, I want to create a complete GenHub backup so that I can restore all my modded profiles, settings, and downloaded content without re-downloading gigabytes of data.
  • UC-2 (Pre-Update Automated Snapshot): As a user updating to a new GenHub version, I want an automatic snapshot taken before the update so that if anything breaks, I can roll back my full environment with one click.
  • UC-3 (Full Environment Cloning): As a player with multiple PCs (e.g. Desktop and Steam Deck/Laptop), I want to export my entire GenHub state to a portable .ghbak archive and import it on my other machine for instant offline play.

3. Technical Architecture & Archive Specification

A. Archive Structure (.ghbak ZIP Container)

backup_2026-08-19_120000.ghbak
├── backup-manifest.json       <- Backup metadata (SchemaVersion, CreatedAt, AppVersion, HashIndex)
├── settings/
│   └── user-settings.json     <- Global preferences, tools, and launcher configurations
├── profiles/
│   ├── {profileId-1}.json     <- Individual GameProfile JSON definitions
│   └── {profileId-2}.json
├── manifests/
│   ├── {manifestId-1}.json    <- ContentManifest definitions (file trees + SHA256 hashes)
│   └── {manifestId-2}.json
└── cas-pool/
    ├── 36/
    │   └── 36565177e8...      <- Raw deduplicated content blobs
    └── f4/
        └── f4f4daa96c...

B. Deduplication & Space Efficiency

  • Because CAS is inherently hash-addressed by SHA-256, all assets shared across multiple profiles (e.g. base game files, community patches) are stored only once in the archive.
  • Deflate / Zstandard compression applied to the archive achieves 40–60% space savings on game assets.

4. Proposed Interfaces & Data Models

namespace GenHub.Core.Interfaces.Storage;

public interface IFullSystemBackupService
{
    Task<OperationResult<string>> CreateFullBackupAsync(
        string destinationDirectory,
        IProgress<BackupProgress>? progress = null,
        CancellationToken cancellationToken = default);

    Task<OperationResult<BackupSummary>> InspectBackupAsync(
        string backupFilePath,
        CancellationToken cancellationToken = default);

    Task<OperationResult<RestoreResult>> RestoreFullBackupAsync(
        string backupFilePath,
        RestoreOptions options,
        IProgress<RestoreProgress>? progress = null,
        CancellationToken cancellationToken = default);
}

public sealed class BackupManifest
{
    public int SchemaVersion { get; set; } = 1;
    public string AppVersion { get; set; } = string.Empty;
    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
    public int ProfileCount { get; set; }
    public int ManifestCount { get; set; }
    public long TotalCasBytes { get; set; }
    public int CasObjectCount { get; set; }
    public Dictionary<string, string> CasHashIndex { get; set; } = [];
}

5. UI/UX Wireframe (Settings -> Backup & Recovery)

+-------------------------------------------------------------------------+
| [Settings] > [Backup & Disaster Recovery]                              |
+-------------------------------------------------------------------------+
| Complete System Backup                                                  |
| Create a self-contained offline archive (.ghbak) containing all your    |
| profiles, content manifests, settings, and downloaded CAS game assets.  |
|                                                                         |
| Total CAS Pool: 14.2 GB (223 objects) | Profiles: 6 | Manifests: 12     |
|                                                                         |
| [  Create Full System Backup (.ghbak)  ]   [  Restore From Backup...  ] |
+-------------------------------------------------------------------------+
| Automated Snapshots                                                     |
| [X] Automatically create a safety backup before applying app updates   |
|                                                                         |
| Recent Snapshots:                                                       |
| • 2026-08-18 (Pre-Update v0.0.1282) - 14.2 GB      [Restore] [Delete]   |
| • 2026-08-10 (Manual Backup) - 11.8 GB             [Restore] [Delete]   |
+-------------------------------------------------------------------------+

6. Acceptance Criteria

  • CreateFullBackupAsync packages Profiles, Manifests, Settings, and CAS objects into a .ghbak archive.
  • InspectBackupAsync reads and validates the archive manifest without extracting all multi-GB blobs into RAM.
  • RestoreFullBackupAsync restores CAS blobs into the target CAS pool, verifies SHA-256 integrity, and restores manifests and profiles.
  • Pre-update hook in VelopackUpdateManager captures an automatic snapshot before executing update installation.
  • Full unit and integration test suite in GenHub.Tests.Core.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions