82de6cae36
PLAN.md §11 *Auto-update* described "check on launch and once per N hours; offer install on next restart, never auto-restart". v0.1.0 shipped checkForUpdates() and applyUpdate() Q_INVOKABLEs but only manual triggers — no scheduling. This wires the polling. armAutoUpdateOnFirstOnline() runs from setState(Online) in bundled mode: - A QTimer::singleShot fires checkForUpdates() 10 s after the first Online transition (lets cold-boot bandwidth/CPU settle first). - A recurring QTimer fires checkForUpdates() every 6 hours after that. - One-shot guard via m_autoUpdateArmed so reconnect cycles don't re-arm the timers. Dev mode skips entirely (developers don't want their `make dev` workflow polling AppImageUpdate). Env-var knobs: - BRIDGE_AUTO_UPDATE_DISABLE=1 — skip entirely (respect-opt-out baseline; user-facing settings UI can layer on top later). - BRIDGE_AUTO_UPDATE_PERIOD_MIN=<minutes> — override the period (handy for testing or shorter intervals on power-user opt-in). The actual install (apply + restart) stays manual — never auto- restart, per PLAN.md's UX rule. checkForUpdates emits updatesAvailable(); QML decides whether/when to show a banner and call applyUpdate(). Verified locally with QT_LOGGING_RULES=phpqml.bridge.bundled.info=true: "phpqml.bridge.bundled: auto-update armed: launch check in 10000 ms, period 360 min" appears in the host log after the BackendConnection probe sees /healthz=200. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>