RFC-042

Updater Spec

Production Specification

Client-Driven In-App Update Engine & Manifest Protocol

A zero-backend update orchestration architecture powered by a single static update.json served via GitHub Pages or a CDN edge. Designed for Android and multi-platform open-source clients requiring fine-grained release ring control, architectural asset matching, and remote emergency lockdown capabilities.

Version Floor
Enforced Min Build
Multi-Ring
Stable / Beta / Alpha
Kill Switch
Global & Per-Channel
Integrity
SHA-256 Digest

1. The Master Manifest Schema

Save this complete payload as update.json on GitHub Pages or CDN.

payload / update.json application/json
{
  "killSwitch": {
    "global": {
      "enabled": false,
      "title": "Service Temporarily Suspended",
      "message": "All app operations are temporarily paused for backend database maintenance. No action is required. Please check back shortly."
    },
    "alpha": {
      "enabled": false,
      "title": "Alpha Testing Ring Paused",
      "message": "A critical memory leak was discovered in the v1.4.0 alpha tree. Alpha usage is halted while an emergency build is prepared."
    },
    "beta": {
      "enabled": false,
      "title": "Beta Staging Paused",
      "message": "Beta builds are temporarily locked due to scheduled authentication server migration."
    }
  },
  "stable": {
    "versionCode": 105,
    "versionName": "1.2.0",
    "minSupportedVersionCode": 102,
    "releaseDate": "2026-09-07",
    "updateType": "OPTIONAL",
    "deprecationMessage": "Your installed version has reached end-of-life and can no longer synchronize. Please update to 1.2.0 to continue.",
    "changelog": [
      "Security: Patched session token leakage across webview boundaries.",
      "Performance: Optimized SQL queries cutting startup duration by 35%.",
      "Feature: Added native system font selector and dark mode toggle."
    ],
    "downloads": {
      "directApk": "https://github.com/USERNAME/REPO/releases/download/v1.2.0/hub-stable.apk",
      "github": "https://github.com/USERNAME/REPO/releases/tag/v1.2.0",
      "obtainium": "obtainium://add/https://github.com/USERNAME/REPO",
      "fdroid": "https://f-droid.org/packages/YOUR.PACKAGE.NAME"
    },
    "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
  },
  "beta": {
    "versionCode": 106,
    "versionName": "1.3.0-beta.2",
    "minSupportedVersionCode": 104,
    "releaseDate": "2026-09-07",
    "updateType": "RECOMMENDED",
    "deprecationMessage": "This beta milestone has lapsed. Update immediately to prevent staging sync timeouts.",
    "changelog": [
      "Preview: New peer-to-peer manifest indexing engine.",
      "Fix: Addressed intermittent crash during bulk import."
    ],
    "downloads": {
      "directApk": "https://github.com/USERNAME/REPO/releases/download/v1.3.0-beta.2/hub-beta.apk",
      "github": "https://github.com/USERNAME/REPO/releases/tag/v1.3.0-beta.2",
      "obtainium": "obtainium://add/https://github.com/USERNAME/REPO"
    },
    "sha256": "7a35e4d298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b899"
  },
  "alpha": {
    "versionCode": 107,
    "versionName": "1.4.0-alpha.1",
    "minSupportedVersionCode": 106,
    "releaseDate": "2026-09-07",
    "updateType": "OPTIONAL",
    "deprecationMessage": "Experimental build expired. Download the newest nightly iteration.",
    "changelog": [
      "Experimental: Completely redesigned navigation rail.",
      "Warning: Local SQLite database structure is in active churn."
    ],
    "downloads": {
      "directApk": "https://github.com/USERNAME/REPO/releases/download/v1.4.0-alpha.1/hub-alpha.apk",
      "github": "https://github.com/USERNAME/REPO/releases/tag/v1.4.0-alpha.1",
      "obtainium": "obtainium://add/https://github.com/USERNAME/REPO"
    },
    "sha256": "cca9e3c988e01083431f476a6cf5ebca5f72e382b6b0c2049e7b25bc8885b546"
  }
}

2. Key-Value Dictionary & Type Definitions

Exhaustive definitions, validation constraints, and behavioral guarantees for every schema token.

"killSwitch" Object • Scoped Lockdowns

Encompasses emergency controls that immediately halt client execution without requiring an APK compilation or deployment. Evaluated before any version comparison.

.global Blocks every user across all channels (Stable, Beta, Alpha). Used for zero-day server outages or severe database risks.
.beta Blocks only clients currently running builds belonging to the Beta channel ring.
.alpha Blocks only clients currently running nightly or alpha testing builds.
enabled: Boolean — When true, app locks out immediately.
title: String — Modal header displayed on the blocking overlay.
message: String — Explanatory paragraph informing the user why the app is temporarily unavailable.
"stable" | "beta" | "alpha" Channel Config Objects

Contains release definitions for a specific distribution track. The client determines which track to consume based on user settings.

Key Type Purpose & Client Rule
versionCode Integer Strictly monotonic positive integer. The sole source of truth for checking if an update exists: remote.versionCode > local.versionCode.
versionName String Human-facing release label (e.g. "1.2.0"). Strictly for UI presentation; never parse programmatically.
minSupportedVersionCode Integer The absolute floor. If local.versionCode < minSupportedVersionCode, the app halts all activity and triggers an unconditional hard update, superseding an OPTIONAL updateType.
releaseDate String (ISO 8601) Publication stamp formatted as YYYY-MM-DD. Displayed in dialog info tags.
updateType Enum String One of: "OPTIONAL", "RECOMMENDED", or "CRITICAL". Controls dialog dismissibility.
deprecationMessage String (Nullable) Contextual message displayed specifically when the client is blocked by minSupportedVersionCode.
changelog Array of Strings Line items describing changes. Client renders these as bullet points in the update dialog.
downloads Object Dictionary containing distribution URIs for automated download, manual web mirrors, and package managers.
sha256 String (64 hex chars) Cryptographic hash of the compiled APK. Checked after download to ensure the binary is not corrupt or tampered with.
"downloads" Object Target Links & URIs
downloads.directApk

Direct HTTPS link to the binary asset. Used by in-app downloaders to silently fetch the payload into the cache directory before passing to the system installer.

downloads.github

Web release page URL. Provided for users who prefer downloading via external web browsers.

downloads.obtainium

Custom URI scheme (obtainium://add/https://...). Tapping this instantly opens the Obtainium app tracker and registers your repository in one step.

downloads.fdroid

Direct link to the F-Droid store client package listing. Normally omitted on alpha or nightly release blocks.

3. Update States & Client Enforcement Modes

How client UI layers must react across different evaluation triggers.

OPTIONAL Urgency: Low

Standard Release

Standard iterative improvements, minor bug fixes, or non-breaking UI adjustments.

  • •Dismissible modal or bottom sheet.
  • •Provides "Update Now" and "Later" buttons.
  • •App functions with zero restrictions.
Dismissible: YES • Blocks App: NO
RECOMMENDED Urgency: Medium

Advisory Warning

Older APIs will sunset soon, or an annoying non-fatal glitch has been remediated.

  • •Dismissible banner or badge.
  • •Re-prompts user on subsequent app launches.
  • •User can continue working if needed.
Dismissible: YES • Re-prompts: LAUNCH
CRITICAL Urgency: Mandatory

Compulsory / Floor Trigger

Triggered when updateType == "CRITICAL" OR local < minSupportedVersionCode.

  • •Non-dismissible full screen modal.
  • •System back button and touch-outside disabled.
  • •"Later" button completely removed.
Dismissible: NO • Hard Execution Lock

4. Interactive Evaluation Simulator

Test how different client states evaluate against the manifest in real time.

Try 101 (Floor fail), 104 (Needs update), or 105 (Latest).
Evaluation Engine Output Ready

System Awaiting Run

Configure client version and channel parameters on the left to simulate update engine decision routing.

Status: IDLE • Ready for test

5. Fundamental Principles: Why This Architecture Works

The Power of Pure Monotonic VersionCodes

Lexical semantic string parsing (e.g. comparing "1.2.0-rc1" vs "1.2.0-beta.2") is inherently error-prone across different operating systems. Standardizing on a strictly increasing integer (101 → 102 → 103) turns the update test into a bulletproof mathematical evaluation (>).

Cryptographic File Integrity (SHA-256)

Downloading binary APKs over mobile towers or public Wi-Fi risks connection truncation or hostile MitM injection. By computing the SHA-256 hash of the local download buffer and checking it against the manifest digest, the app prevents corrupt package installs before ever passing the payload to Android's PackageInstaller.