vibe-viewerDocumentation

Supporter recognition and website updates

Planning proposal, 2026-11-08; implementation progress updated 2026-11-10. No release assignment. The support-page menu and check/download controls are implemented on main. Verified badges, the shared service and safe in-app installation remain planned. Source implementation is not installed-package acceptance or evidence of a published update feed.

Existing base and intended result

Electron already depends on electron-updater and configures its generic HTTPS provider at https://vibyverse.com/updates/vibe-viewer/. main.js has Check for Updates, a startup check, download handling and a manual fallback for macOS builds that cannot self-install. Its current platform gate includes packaged macOS arm64 and Linux x86-64 AppImage applications; source launchers are excluded. Source documentation now distinguishes enabled feed checks from actual publication; verify each delivered channel under #197. The support-page menu described below is available; verified badges and the provider-linking service are not yet implemented.

The new Upgrade to Supporter… item should offer Ko-fi and GitHub Sponsors, plus I already support / Restore recognition. Successful verification adds an optional Supporter badge in Help/About and a small account/status area. Recognized users get manage, refresh, hide and unlink actions. Use the same wording and recognition contract across Viewer, Sketcher and Scheduler, with an app-specific implementation appropriate to each product’s UI.

Recognition is cosmetic: it does not lock scientific features, add watermarks or require runtime activation. An installed viewer keeps working offline and after support ends. Source licensing and redistribution rights remain unchanged. The badge stays local and opt-in; publishing a supporter name or directory is outside the first scope. CLI/headless use needs no supporter account.

Shared website recognition contract

The website/backend owner handles provider integration; apps consume one provider-neutral contract, rather than each shipping a payment backend. Canonical shared-contract tracking starts in Viewer #195. Other products should reference that contract and keep their own client issues. Website implementation, credentials and operational configuration belong in their owner’s repository; this plan does not authorize another repository’s implementation or deployment.

The intended flow is:

  1. The user chooses a provider or restore action. The app opens the system browser to the website’s linking/claim flow with a short-lived session-bound nonce/code. Payment and provider sign-in remain outside the app renderer.

  2. The website verifies identity and contribution using provider events and supported reconciliation. GitHub identities must be authenticated; a Ko-fi claim must prove control of the payment identity. A claimed email, screenshot or checkout redirect is insufficient. Unresolvable anonymous records need a documented assisted claim, not a public supporter lookup.

  3. The website exchanges the one-time authorization for an app-verifiable signed receipt: opaque subject, product/audience, recognition status, last-verified and validity information, key ID and signature. Define restore, refresh, unlink, revocation and signing-key rotation in the versioned contract.

  4. The app stores credentials in protected per-user storage and keeps recognition scoped to that user/session. Shared browser servers must not share one user’s badge or credentials with another. Receipts, credentials and payment details do not enter QVF, figures, document exports or routine logs.

  5. Cached recognition remains useful offline, labelled with its verification state. Expired verification must not assert an active subscription. A service outage affects recognition refresh or protected downloads, not local viewing.

GitHub Sponsors provides lifecycle webhooks. Ko-fi’s API reports payment events, but does not notify when membership ends. Both require authenticated, idempotent event handling; missed or reordered events need reconciliation. Ko-fi renewal/paid-through expiry cannot depend on an invented cancellation webhook.

Proposed first recognition scope is any verified one-time or recurring contribution. Record the recognition duration and recurring paid-through/grace rules before implementing enforcement. These are product-policy choices, not facts inferred from provider API behavior. Cosmetic recognition, current membership and permission to download a particular binary are distinct fields. Store purchases remain separate from website supporter recognition.

Website-hosted automatic updates

Yes: the updater can pull from our website. Reuse the existing generic HTTPS provider; do not create a second updater. A public feed can use ordinary static HTTPS hosting or a CDN. The publisher must upload the generated update metadata, payloads and required blockmaps; the generic provider does not deploy them itself. This is supported by the pinned builder generation’s electron-builder v26 updater.

Installed product/channel

Planned update owner

Approved website AppImage

Website feed, correct Linux architecture and writable installation

Approved direct macOS application

Website feed; qualified signing and macOS update ZIP/payload required

Approved direct Windows installer, if added

Its separately qualified website feed/installer; not assumed from the existing NSIS target

Mac App Store / Microsoft Store edition

That Store’s update mechanism; never replace it with a website binary

Source checkout, pip or package-manager installation

Its existing installer/package-manager workflow; no in-app shell update

Unknown or unqualified package

Clear manual replacement instructions

Select the install kind/channel explicitly at build time and verify it at runtime, including Store detection. Keep architecture, OS minimum, product and release-channel checks separate; a matching OS alone does not select a payload. Store checkout/link presentation also needs its channel/region configuration; the website’s support links are not automatically suitable for Store binaries. See the Apple review guidelines when preparing an Apple Store edition. This plan does not select a new Store payment mechanism or add a direct-download platform channel.

Extend the updater UI to report checking, current version, release notes, available, downloading/progress, ready, retry and failure states. Give the user control over automatic checks/downloads. Installation requires an accepted restart, resolution of unsaved edits/recovery state and clean Python-backend shutdown. Disable automatic install-on-exit until it follows that same path. Do not force a restart or modify a source checkout from the app.

Feed delivery, trust and access

Reuse the existing update origin/path and documented legacy redirects. Feed identity must distinguish product, platform, architecture and channel. Stage immutable versioned artifacts first, verify their final URLs, hashes, signatures and range responses, then atomically promote their generated manifest. Define cache headers, content types and an allowed redirect policy. Never overwrite released bytes. Candidate qualification and operator-controlled publication remain the existing release process; this is not automatic publication of main.

Use platform signature validation where supported. Linux also needs an explicit publisher-authenticated metadata/artifact contract, trusted verification keys, rotation and downgrade/replay handling: do not assume a generic AppImage feed already supplies these checks. A checksum detects changed bytes; publisher authentication establishes who authorized them. Qualify the verifier with the actual updater before selecting its implementation/dependency. Bind the verified manifest/YAML and artifact hashes to the exact descriptor and payload bytes used through installation. A later metadata fetch must pass verification again; verification of an index alone cannot authorize replacement YAML fetched afterwards.

This plan does not change whether official downloads are public or require membership. That is a separate distribution-policy decision. If a channel’s approved policy protects downloads, a static public URL cannot enforce it: the website must authorize each protected payload/range/blockmap request or provide short-lived scoped URLs. The existing updater supports authorization headers, but redirect, CDN and token-expiry behavior still needs qualification. Badge state alone never authorizes a protected download. Public source/notices and already installed functionality remain independent of website membership. Existing public clients/downloads need a compatible migration before any access restriction is promoted; Store updates remain independent of this service.

Recovery must cover interrupted downloads, stale or partially published feeds, wrong architecture/channel, corrupt or wrong-signer payloads, expired access, offline service, read-only installs and low disk space. Retain user documents, settings and recovery data; provide a verified manual reinstall/previous-package route when self-install fails. Withdrawing bad metadata does not downgrade an installed app automatically or replace immutable release artifacts.

Work packages and sequence

Implemented menu slice, 2026-11-09 (#196): Upgrade to Supporter… is in desktop Help (also the macOS application menu), browser Info and About. Its dialog explains that support is optional and badges/account linking are not yet available. An explicit Open support page action opens the project’s https://vibyverse.com/#support section; provider destinations stay managed on the website. That section and its Ko-fi link were live when checked; GitHub Sponsors onboarding remains pending in vibyverse/vibe-scheduler#242. No receipt, badge, account claim or restore action is simulated. Store/MSIX launches omit the native and browser links; operators can also suppress them with VIBEVIEWER_SUPPORT_LINKS=0. #196 remains open for the verified flow after the shared #195 contract and policy are ready.

Implemented slice, 2026-11-09 (#197): native check/status results and retry, bounded progress and release notes, persisted startup-check/automatic-download preferences, Store/MSIX exclusion, source/manual routing and same-origin/path manual download links. Startup checks default on and automatic downloads off. Automatic installation on exit is disabled, and the previous restart/install action is replaced by manual payload reveal/replacement while recovery-aware installation is pending. Fake-provider and real-main-process menu checks cover success, failure, settings, routing and the absence of installation calls. Full feed trust, provider services and installed upgrades remain open; this slice does not select supporter policy or a trust protocol.

Implemented build-identity slice, 2026-11-09 (#197): the packaging hook writes a per-output product/version/platform/architecture/install-kind/channel record before signing. The updater requires a matching stable supported package before querying its website feed. Missing/corrupt/mismatched records, unpacked previews, mixed installation targets and prereleases receive manual guidance. Windows NSIS is identified but still manual; Store/source routes stay independent. This local build record is not authenticated feed metadata or a signed supporter receipt.

Implemented cancellation slice, 2026-11-09 (#197): native update status can cancel the current transfer using the existing updater’s cancellation token. Stopping/cancelled states, fresh-check retry and session-local suppression of automatic re-download preserve that choice. Completion races and stale dialogs cannot expose a cancelled payload or cancel a newer retry. Quitting stops an active transfer; late check/download callbacks are drained without notifications. This does not install a downloaded update or change persistent preferences.

Implemented failure-recovery slice, 2026-11-09 (#197): known updater/I/O codes produce actionable network, disk-space, permission, integrity/signature or invalid-feed guidance. Failure diagnostics store only a fixed category and operation, without raw diagnostics or credentials. Late success events cannot turn a failed check/download into an available or ready payload. Check again checks fresh metadata without automatic downloading for that check; saved preferences remain unchanged. Open downloads opens the fixed official website page, independently of the rejected feed/payload URL. A real pinned checksum-verifier failure and real main-process recovery actions are covered. This is source acceptance; authenticated publisher trust, installation into read-only locations and installed-upgrade qualification remain open.

Implemented leave-warning slice, 2026-11-09 (#197): browser close/reload/ navigation warns for edited or in-memory geometry across open readers, unsaved session changes and recovery errors. Geometry exports and recovery snapshots do not acknowledge a saved source or client download. Native Stay / Leave defaults to Stay; cancellation preserves the backend/updater, title and recent file context. Teardown occurs at Electron’s accepted will-quit, rather than the cancellable before-quit. Real Chrome/Trame checks cover warning, cancelled navigation/state retention and clean navigation; native event/menu fixtures cover cancellation, accepted teardown and navigation races. This does not checkpoint pending jobs, prevent forced shutdown or authorize installation. The multi-process recovery/install handshake and installed acceptance remain open with publisher trust under #197/#198.

Implemented recovery-retry slice, 2026-11-10 (#197): failed prepared snapshots remain in bounded, per-reader memory buffers for Retry saving drafts. The action captures the active document and retries inactive snapshots without changing the active reader or mixing undo/view state. Save errors remain visible by document after file switches and unrelated successful saves. Previous committed bytes survive failure; explicit discard cancels the matching pending save. Invalid newer snapshots and buffer limits remain errors rather than being acknowledged by older payloads. Buffers use the existing per-draft/count/total serialized-data budgets and are not durable until saved. This is a prerequisite for recovery-aware updates, not the cross-process checkpoint or install handshake.

Implemented owned-viewer snapshot request, 2026-11-10 (#197): desktop Update settings offers Save recovery for open viewers…, covering live viewers started by that app’s directory server. A private loopback protocol requests current recovery and returns fixed saved/busy/failed counts, with changed-process detection, bounded fan-out/deadlines and no redirects. Tokens remain outside renderer/console state and are not persisted. Known local work/render locks, discarded or stale geometry, recovery errors and unsaved display-only sessions cannot pass; a busy console is also reported. Missing/old services keep manual per-viewer controls. Source checks include a real directory → Trame viewer → native request-client round trip. Editing remains enabled: this is a snapshot request, not a frozen all-job checkpoint, quit or installation authorization.

Implemented accepted-quit exit acknowledgement, 2026-11-10 (#197): Electron waits for its owned backend after every viewer accepts closing. An authenticated shutdown request enters the directory server’s registered-child cleanup; receipt alone does not acknowledge exit. POSIX also checks its dedicated process group. Windows cleanup stops live viewer trees and retains the owning server on a tree failure, allowing explicit native force. Stalls offer Keep waiting / Force quit, defaulting to waiting; failed force cannot authorize exit. Quit requests coalesce and cannot reopen the backend. A real directory/Trame-child/group exit passed locally; Windows behavior has focused command/lifecycle checks, with installed-channel acceptance still pending. This does not freeze edits, create an all-job recovery checkpoint or enable installation.

Tracker

Work

Responsibility/dependency

#195

Shared provider verification, receipt and membership/recognition contract

Website/backend owner; owner not yet assigned

#196

Viewer Upgrade to Supporter menu, restore/manage flow and optional badge

Viewer; synthetic fixtures first, verified activation depends on #195

#197

Viewer channel-aware updater, user controls and safe install/recovery

Viewer; extends existing updater, consumes #198

#198

Shared website feed publication/trust contract and optional download authorization

Website/release owner; #195 only for protected channels; joint installed acceptance with #197

First settle the shared recognition and feed contracts and the product-policy choices above. Implement client UI against synthetic fixtures and qualify public feed delivery independently of supporter sign-in. Connect real provider verification and any approved protected-download flow next. Finally accept real previous-version installed upgrades for each enabled channel, including bundled runtime, reopen and document/recovery preservation. Source/UI tests or HTTP success alone do not establish that an installed update works. Ordinary development skips CI; release candidates use the existing full qualification.

References: roadmap, distribution, release process, the source tree’s electron/PUBLISHING.md packaging notes.