← Sketches · the native app program

An update and its states

c1392026-11-11

Nine states from up to date to managed elsewhere, three preferences, one trace, and the same page in two eras: build partners now, a structured rollout later.

Source: c139 initial-prompt.md (Mark's words, 2026-11-11); c139 plan.md §The shape (what is updated, the feed, the states, the preference, the trace, two eras), §Rules R1–R7, D1–D16 (proposed, for review-1), T1–T6 (Tyler); c139 prior-art.md; c130 research/platform.md §5 (qupdate, Zed's status machine); c137 plan D9 and inventory row 24; c62 and /partner-digest (the notes' sources).

The plumbing: qupdate's half exists; the face is this cycle's
⬓The feed

CI's sidecar beside each binary: version, git_sha, ref, published_at, artifact, sha256; asked for now: channel, notes, size; later: rollout, min_version, pulled (T3)

hourly
⬚The updater

qupdate grown bundle-aware, or the app's own (T2); download, checksum, stage, replace; elevates only for qcontrol (T4)

per binary
▣The state machine

the app and qcontrol, each with its own state, on one page with one Update (D9)

one sentence
▭Settings › Updates

the state, the versions, the preference, the channel, the notes

▭The footer and the tray

the trace: updated, 0.2.0 ready, Restart to update

The path, when nothing goes wrong
1Up to date

the newest on the channel; checked hourly, or Check now

2Checking

asking the feed

3Available

the current and new version, published, size, the notes; Update

4Downloading

download · verify (the checksum) · stage beside the running app; cancellable until staged

5Ready to restart

qcontrol keeps watching while the app restarts (R2); Restart now · When I quit

6Installed, then what's new

restarted into it, quietly or by the person; the notes lead the page

Failed

a download, checksum or replace did not complete; nothing changed and the page says so. Three failed tries reach the tray as one line (R3's exception).

Offline

the feed is unreachable; not our error and not the person's problem: last checked, and when it tries again.

Managed elsewhere

a package manager now (Homebrew: the command to run); later the organisation's policy from the plane (a pinned version, Contact IT). The preference is shown, locked, with the reason (D10).

The preference: checks always run; it decides what follows (D1 tinted)
Install updatesDownloadsInstallsWhat you see
Automaticallythe default (D1): invisible, never untraceablein the backgroundat quit, at restart, or idle with the window closed (D3)the trace, afterwards
Ask me firstin the backgroundwhen you say Restartthe tray's dot and line; the footer's "0.2.0 ready"
Manuallywhen you press Updatewhen you say Restartthe Updates page and the tray's "Update available"
Silent leaves a trace, never a prompt (R3, D2)
  • The footerv0.2.0 · updated, for seven days; a click opens Settings › Updates. It already names the source and the version (c131 R1).
  • Updates pageleads with "Updated to 0.2.0 yesterday at 18:02" and what's new; the history says how each version came.
  • The trayone line while there is something to do; the version line says "updated". A dot only where the person asked to be asked.
  • Notno inbox message (c137 row 24 stands), no OS notification, no toast, no dialog. A quiet install never asks for a password: qcontrol's part waits on the page.
Now: build partners · one channel, the feed as qupdate has it plus notes
One channel

every build CI publishes with a tag reaches every partner at once; a pulled release is the only brake (T3)

▤Internal notes, inline

what changed, sharp edges fixed, known ones, each line with its source; drafted from the cycle records at release time, gated by whoever cuts it (D6, D7); the trail one link away

The tag and the SHA

0.2.0 · a3f9e12, and Copy version info for a bug report (D5)

Later: a structured rollout · the same page reading more fields (D12, R7)
Stable and Beta

partners on Beta, with internal notes; back to Stable waits until Stable passes your version

Staged by percentage

each install draws a stable number; a bad signal halts the rollout; min_version is the security floor

▤Public notes and the organisation's policy

three lines and the changelog; from the plane (c134): the channel allowed, a pinned version, an update window. Never a person's skip (R6, D8).

the state machine: the protocolwhat this cycle designs, in the partner eraexists already, or laterTyler's call, or the failure pathnot decided, or someone else's
The problem
The native app will change weekly on machines whose owners watch what it costs them, and the updater we have (qupdate) has no face: no states anyone can read, no preference, no notes, no restart, no word for "someone else manages this". Build partners should see our internal notes; a customer in a staged rollout should not.
The core idea
One page, one state machine, three preferences, two eras. Every state says what is true and what happens next. Silent means nothing interrupts, not that nothing is said. The era is data from the feed, not a flag in the app, so the later rollout is the same page reading more fields.
What is open
For Mark (review-1): the preference's default, what silent means, inline or linked internal notes, skip, who owns the notes, one update or two, when an automatic install may restart. For Tyler: signing, which updater, the feed's fields, the sensor's update and its gap, knowing a package manager owns the install, restart mechanics.

Qpoint Brand Style Guide