Skip to content

v0.8.0

Latest

Choose a tag to compare

@github-actions github-actions released this 23 Oct 11:34
· 5 commits to main since this release
Immutable release. Only release title and notes can be modified.
v0.8.0
f2110ad

v0.8.0 — qualified stable release

This release supersedes v0.7.7 as GitHub Latest. Its signed candidate qualification is recorded in docs/RELEASE_STATUS.md; planned combinations below are not evidence until that campaign passes. Supported platform families (Linux, macOS, and Windows hosts; Chromium-based browsers, Firefox, and Safari/WebKit) are tested in CI, not qualified; see docs/COMPATIBILITY.md. Neither claims unnamed hosts, browsers, OMP builds, or remote-access paths.

Highlights since v0.7.7

  • This release uses stock OMP v18.12.5 as its engineering baseline. The 39 changelog entries below record the changes since v0.7.7. Historical receipts do not qualify these bytes.
  • Explicit release_class=minor release requests select the next minor version, bind that class through preparation and promotion, and fold an unpublished patch preparation into the new cut without rewriting immutable candidates. Scheduled and default requests remain patch-only.
  • Opt-in multi-host federation via browser-direct CORS (ADR-036): fleet.label (defaulting to the first DNS label of the http.publicOrigin host, while loopback dev origins keep the literal host) and fleet.targets (up to 7 remote origins; 8 sources total with local), http.trustedDashboardOrigins (up to 8 canonical dashboard origins), GET /api/v1/client-config (schemas/client-config.schema.json; 404 on older gateways falls back to local-only with speech off, while an invalid or origin-mismatched 200 shows Fleet configuration unavailable — reload this app with the local directory still working), and exact-origin CORS admission in apps/gateway/src/http-policy.ts restricted to GET /api/v1/sessions, POST /api/v1/sessions/:instanceId/launch, and their authenticated OPTIONS preflights (which never consume launch rate-limit tokens; requestHasTrustedDashboardContext), refusing any foreign non-admitted Origin on /api/ routes (except loopback GET /api/v1/health) with 403 before identity checks, with no server-side proxying and home-scoped Web Push.
  • All hosts view and Host picker in OMP Sessions: host labels on every row, Up next hero card, On hold row, and active collaboration shell bar; browser-observed waiting order (observed waiting order) across hosts while preserving ask.since FIFO within a single host; truthful All clear and No live sessions states only when every host in scope has a fresh snapshot; remote polling every 10 s while visible with a 5 s request timeout, 35 s stale grace (Cannot reach this host from this app.), and readable 403 → forbidden (Access withdrawn.) until Retry or foreground transition.
  • Source-bound collaboration recovery and lifecycle: CollabEmbedOptions.probeGateway coalesces GET <source>/api/v1/sessions ("healthy" | "unavailable" | "forbidden", with "forbidden" setting gatewayHealth.state = "forbidden" and showing Access withdrawn in the embedded shell chip without relay refresh or automatic probe retry) while keeping the default same-origin /api/v1/health probe when omitted, and pagehide/pageshow resume preserves the originating source binding.
  • Speech input in writable Control (#380, ADR-037): documented OS keyboard dictation baseline (Permissions-Policy: microphone=(), help copy "Use your keyboard's microphone key to dictate into this box. iPhone: Settings → General → Keyboard → Enable Dictation. Dictation never sends — tap Send when the text is right.") plus opt-in in-page Web Speech recognition (speech.browserRecognition, CollabEmbedOptions.browserRecognitionEnabled, SpeechInput; lang = navigator.language || "en-US", continuous, interimResults, one alternative, no auto-restart; watchdogs 10 s start, 120 s capture, 5 s stop; bounds 128 segments, 8,000 code points, 32 KiB) with the pre-start privacy disclosure "Your browser or OS may send audio to its speech provider before any OMP prompt is sent." and strict separation between Use text (draft insertion) and Send (prompt submission). Issue #380's installed-iPhone acceptance remains pending physical-device verification.
  • Tern execution-environment guidance, qualification procedure, acceptance matrix, and 2026-10-22 developer-workstation smoke evidence (Smoke-tested, not CI and not release qualification: Tern 0.9.5 build 2863c37 on macOS Apple silicon with stock OMP 18.12.6 one patch release above the v18.12.5 engineering baseline pin, two dev-localhost gateways, colliding instanceId rows, remote View/Control preflight and launch, prompt and ask round-trip, remote outage isolation, and injected SpeechRecognition UI smoke; Tailscale Serve, phone/installed PWA, Tern /new//fork/reconnect, native browser speech recognition, and Pixel/iPhone keyboard dictation remain pending) in docs/OMP_INTEGRATION.md, docs/COMPATIBILITY.md, docs/TEST_PLAN.md, and ADR-038.
  • Document HTML responses extend Content-Security-Policy connect-src with configured fleet.targets[].origin (never http.trustedDashboardOrigins) and set Permissions-Policy: microphone=(self) only when speech.browserRecognition is true; API, SSE, problem, and static asset responses retain connect-src 'self' wss://my.omp.sh and microphone=().
  • Migrate device-local triage storage in localStorage to omp.sessions.held-asks.v2 and omp.sessions.dismissed.v2 carrying sourceId and sourceOrigin. omp-gateway install preserves http.trustedDashboardOrigins, fleet, and speech verbatim, while omp-gateway rollback to a retained runtime older than FLEET_CONFIG_SINCE_VERSION (0.8.0) writes the full authored document to <configDir>/config.pre-rollback.json (0600, refusing if that file already exists), removes http.trustedDashboardOrigins, fleet, and speech from config.json, and prints restore steps (install 0.8.0 or newer, replace config.json with the backup, restart, reload the PWA); the next release must therefore be 0.8.0.
  • Advisory Percy visual review of 18 deterministic, authored synthetic states across phone, 810×1080 tablet and desktop CSS viewports, with fail-closed serialized DOM/resource canary guards and source/serialized layout parity. CI always validates locally and uploads only for same-repository PRs, main pushes and GitHub-hosted dispatches; forks and gateway-ci dispatches receive no Percy secret. No production source or runtime assets change.
  • BrowserStack setup/baseline/renewal runbook and ADR-035 separating Percy visual review, TestingBot release deviceCloud, Automate fallback under ADR-032, and capability-free manual Live review. Sponsorship review is due 2027-09-20 before the 2027-10-20 expiry.
  • Update the development-only Percy CLI from 1.32.11 to 1.32.12; keep the pinned Bun runtime and bundled production dependencies unchanged.
  • Add BrowserStack Automate Mobile as an immediate pre-write fallback for empty TestingBot iPad and Samsung Android pools, keeping iPhone/Home Screen Push TestingBot-only and targets sequential. Pin Local 8.9 under Rosetta with the documented single-user child-argv exception, shared CONNECT containment, private crash-cleaned config, vendor-qualified ownership, per-target release attribution, complete retained-record audits and verified record deletion. Persist signed artifact inventories only in private recovery progress, require every artifact absent before restoration, and re-audit crash cleanup or count unaudited deletions explicitly. Detect opaque failed-command media and canonicalize Local ownership through symlinked paths. Accept references only as whole HTTP(S) string values with one scheme/hostname occurrence and no comma; reject reference-like keys or other values, retaining the exact dashboard exemption. Require each pinned hostname's raw and canonical JSON census to equal accepted reference counts. Extend that census to bounded fixpoint percent-decoded text and a single decoded scheme per reference, with character-class-pinned dashboard paths/queries and no userinfo, ports or fragments. Persist an incident for any unbound pre-build reference instead of retaining volatile pending references; deletion/absence checks still proceed, but fresh cleanup cannot clear the incident. Atomically checkpoint post-audit artifact references with an incident while continuing only deletion/absence verification across crashes, and reject data/media keys using value classification. Keep DELETE and bounded absence checks running after post-audit validation failures by atomically recording an unvalidated-record incident and safely recovered strict-JSON whole-value references. Verify record/log absence before failing for missing inventory, and accept clean XML/text artifact 404 or reviewed media-403 bodies after raw scans/censuses without falsely requiring JSON. Scan every non-media retained-surface body before rejection, whatever its status, including pre/post-audit errors and transient GET-retry bodies, and persist capability hits as incidents. Preserve monotonic cleanup stages and recovery dependencies on release failure. Identify retitled Local descendants by PID/birth lineage, not argv; prepare before owning a tunnel. Keep signed-log expiry limits explicit and refuse the fallback entitlement from 2027-10-20 without a reviewed renewal. Public-page development probes do not qualify a release.
  • Add explicit same-receipt device-cloud availability resumption: finish publication lifecycle before reporting a clean hold, preserve other passed qualification proof, and require one guarded operator authorization per immutable release-driver retry job. Infrastructure holds never pass qualification, auto-retry, or clear ordinary failures or foreign host ownership. Keep machine outcomes in atomic private per-phase files rather than noisy lane stdout, record every hold leaf, consume old resume eligibility before setup, bind both hold scopes to the immutable worker host/source/policy, and replay a failed unclaimed tmux launch in the same job.
  • Widen TestingBot's modern iPhone and Samsung device pools with explicit OS floors and canonical Galaxy hardware checks; keep A55 disabled pending an observed hardware-code proof. Check free inventory during read-only preflight and distinguish typed availability holds (exit 75) from diagnostic failures without changing schema 3 or qualification claims. Audit every partial attempt for exact contiguous 16-character link windows, minimize vendor-logged page results, attest before opening capabilities, and stage the cloud fixture only under the Pixel lease. Keep targets sequential within the vendor's session limit, block queued Pixel lanes after any release failure, and audit raw plus canonical retained metadata, asset inventories and declared logs. A shared strict JSON parser rejects duplicate keys at every depth before discovering references, with a parse-site invariant against lenient bypasses. Application asset checks return only an in-page comparison boolean to vendor command logs.
  • Move the OMP engineering baseline to published v18.12.5 (#423), with pins derived by scripts/upstream-pins.ts. Registry v1, the discovery file format and socket paths, the relay protocol, collab.autoStart, packages/wire/src/index.ts, and every collaboration and collab-web source are unchanged from v18.12.3. Within the tracked paths, only docs/extensions.md documents GitLab MR references for ctx.annotations (can1357/oh-my-pi#16361) and the version bumps touch package.json; neither changes what the gateway reads or sends. The embedded client remains at v18.4.2. No qualification is claimed; published v0.7.7 stays bound to OMP v18.10.2.
  • Move the OMP engineering baseline to published v18.12.3 (#409), with pins derived by scripts/upstream-pins.ts. Registry v1, the discovery file format and socket paths, the relay protocol, collab.autoStart, and the collaboration host.ts, registry.ts, settings.ts, and packages/wire/src/index.ts sources are unchanged from v18.10.2. Session entries gain an optional runtime build identity (can1357/oh-my-pi#15680), a CLI guest's prompt-cache key changes (can1357/oh-my-pi#15467), and the collab-web eval renderer changes (can1357/oh-my-pi#12730); none changes what the gateway reads or sends. The embedded client remains at v18.4.2. No qualification is claimed; published v0.7.7 stays bound to OMP v18.10.2.
  • Rewrite the README, public site home page, and operator and user documentation reader-first. The README leads with the product promise, demo, a three-step quickstart, everyday use, the privacy model, and a two-column supported-platforms table, and drops release-ledger prose, fork-era history, and the architecture diagram. New docs/README.md indexes every document by task (use, trust, build on, dated records) and new docs/USAGE.md explains the directory, View and Control, Needs you, hold and hide, background alerts, app installation, and error states from the phone holder's point of view. docs/OPERATIONS.md keeps its numbered headings but reads as a task guide with a configuration table, doctor check list, and troubleshooting-by-symptom table; installer transaction internals move to docs/ARCHITECTURE.md. docs/UPGRADE_ROLLBACK.md opens with upgrade, rollback, boundary recovery, and what rollback never does, and restores the v0.6.0–v0.7.0 predecessor sections the release ledger links. docs/COMPATIBILITY.md leads with the support table and a plain current claim. Stale current-state claims (v0.4.0 status, Windows and background Web Push "not yet qualified", the ADR-018 worker-navigation gap) are corrected across the root security policy, package READMEs, and runbook introductions; the site home page, llms.txt, and all four site pages gain a Docs link. scripts/docs-links.test.ts fails on any relative Markdown link or heading fragment that does not resolve.
  • Visual QA of the README on GitHub's desktop and phone renders: the install step is now one copyable block (tar, cd, install, serve-guidance, shared with Operations) instead of archive names in prose; the supported-platforms table shows the qualified OMP commit as a short SHA linked to the exact upstream commit so the table no longer scrolls sideways on a phone; the settings-sheet capture appears once, beside the background-alerts bullet. release-generate approve emits the linked short commit.
  • The README adds BrowserStack's open-source attribution ("This project is tested with BrowserStack") below the TestingBot real-device acknowledgement.
  • Confirm disposable Debian droplet deletion when DigitalOcean removes ownership tags before its final HTTP 404. Keep strict id/name/tag checks before DELETE and exact id/name checks during bounded absence polling; a missing tag never counts as absence. Wait for stream establishment before disconnecting it in the browser outage check.
  • Read the release's tag endpoint before declaring it absent from GitHub's release list (#437). Keep the same release-policy and signed-asset checks when a newly published candidate is missing from the list; a missing tag or failed lookup still fails closed.
  • Retain the Linux qualification droplet's create id before waiting for its public IPv4. Null networks and parse/API errors no longer mean resource absence; teardown deletes the bound id, requires HTTP 204/404 and fails if billing remains. Preserve credential-free provider response bodies and statuses as workflow artifacts, including failed cleanup.
  • Allow up to 180 seconds for each authenticated WinRM probe on a fresh Windows qualification instance, still capped by the shared 12-minute allocation/admission deadline and requiring three consecutive successes spanning at least 60 seconds. Retain credential-free per-probe start, first-response, signal and exit timing in Windows progress and evidence, including failed admission and cleanup, without changing qualification pass gates.
  • Fail closed on classified Percy diagnostics from either output stream and refuse snapshot POSTs after an SDK warning. Upload mode now audits the exact redacted CLI-log candidate after an isolated 18-state testing-host run and proves a planted SDK-log canary is rejected. Document that Percy uploads CLI logs with every build; the opt-out disables CI logs only.
  • Run the Percy CLI under native Node instead of Bun's incompatible HTTP server layer, and pin its CI Node 24.22.0 LTS runtime. Preserve sanitized phase/reason/count diagnostics through both runner layers so a created build with zero accepted snapshots cannot hide its failing boundary.
  • Disable automatic Percy drop-in baseline seeding; baseline approval stays manual. Classify CLI diagnostics without exposing their text. Only CLI 1.32.11's exact unconditional future-Node startup notice is nonfatal on the already-pinned Node 24 runtime; SDK/unknown warnings stay fatal.
  • Resolve Percy Node executables through the platform-native lookup (including Windows), and disable test-only CSS animation replay so source/serialized parity does not capture entrance motion.
  • Poll for the installed WebAPK's DevTools page target before judging the published-byte smoke render, with a fail-closed deadline and sanitized timeout diagnostics.
  • Open sessions on tablet and desktop widths are no longer squeezed into the directory's 35rem column (#411, #412). The directory's main rule also sized the embedded client's <main>, so the transcript stayed 542px wide and code lines showed about 45 characters. From 37rem up, the session, its header, and its triage bar share one centered min(100% − 2rem, 60rem) column, and the transcript reaches the client's own 900px width (about 88 characters per code line). The directory keeps its 35rem triage column, and nothing changes below 37rem.
  • The embedded-ask browser test now waits out the relay client's backoff after the relay returns. Its 5-second wait failed on slow runners, because each held reconnect doubles the retry delay to as much as 15 seconds under the test's fixed jitter.
  • The deviceCloud lane reads TestingBot's iPhone session start correctly. TestingBot answers with a W3C value and also echoes the session id at the top level. The lane took that wrapper for the capabilities, so it refused every such allocation as "another platform or browser". This was found by the first Studio development run. Session start now reads the W3C value, still accepts JSON Wire responses, and treats two different session ids as an unidentified create.
  • The iPhone Home Screen install now expands Safari's shortened share sheet on every observed iOS 26 release. The expansion cell is labelled "View More" on 26.4 but "More" on 26.2, so the second development run could not find Add to Home Screen on an iPhone Air. The lane taps only that cell, never Safari's toolbar More button, which dismisses the sheet. Each install step now waits for the element it needs instead of a fixed pause, because an iPhone 17 Pro Max that had passed four times once rendered its menu's Share action later than the former 1.5-second pause.
  • Pin the BrowserStack browser_url, public_url, logs, video_url and insight optimize_url shapes found by the third Studio development run, keeping dashboard/docs hosts unfetched and retaining only fixed audit/parser causes in memory while progress and receipts remain generic.
  • Resolve the BrowserStack contracts exposed by Studio development runs four and five: accept the observed S26 SM-S942U1, ignore non-media capability echoes, track re-signed logs by object identity with the latest persisted URL, diagnose installed-shell timeouts with closed codes, and distinguish completed incident removals from unverified removal.
  • The local Percy health test allows 30 seconds, the portable lane's per-test default. On a cold Windows runner, starting Node and loading @percy/core took longer than its former 10-second limit.
  • Close the PR #421 review gaps: detect nested/raw image retention without treating capability echoes as media, persist every failed BrowserStack audit through deletion/crash recovery, reject conflicting WebDriver ids regardless of capabilities shape, and permit only complete six-key signed-artifact queries plus optional response-content-type.
  • Require the pinned session-bound BrowserStack video_url presentation on finalized records, and detect text-log media under unquoted/single/double-quoted keys and :/= assignments without treating quoted placeholders as retained containers.
  • Preserve running-session media incidents across clean finalization and detect binary image/video signatures in non-media-labelled retained bodies before decoding, retaining the existing bounds, decoded text scans and declared-media body cancellations.
  • Refuse BrowserStack retained text in any encoding other than UTF-8. A declared non-UTF-8 or repeated charset, or a decoded NUL (UTF-16/32 without a byte-order mark), is an incident, so interleaved text cannot hide a capability window from the scan.

Qualified combinations

role combination
Linux host Run 39937344468 succeeded (https://github.com/carrythroughsystems/omp-session-gateway/actions/runs/39937344468); OS/kernel versions and migration counts are not exported.
macOS host VirtualMac2,1, macOS 27.0 arm64; doctor 18/18, rollback 23/23; native addon a9dda5e6640b173279d738c0d13374fcc5daa409d7167ce9ff54ea56bf5afb30.
Windows host Windows x86-64 build 26100; 4 CPUs, 8186 MiB; Administrator upgrade/rollback from v0.7.7 and fresh standard-account lifecycle; interactive logon, not unattended boot.
Chrome and Chromium Pixel 8 Pro, Android 17, Chrome 155.0.8059.84; TestingBot, tunnel 4.9: Galaxy S26 (16.0.0, chrome 145.0.7632.159)
Safari and WebKit TestingBot, tunnel 4.9: iPhone 17 Pro (26.5, safari 26.5); TestingBot, tunnel 4.9: iPad (9th generation) (26.6, safari 26.6)
Android Pixel 8 Pro, Android 17, Chrome 155.0.8059.84; TestingBot, tunnel 4.9: Galaxy S26 (16.0.0, chrome 145.0.7632.159)
iPhone and iPad TestingBot, tunnel 4.9: iPhone 17 Pro (26.5, safari 26.5); TestingBot, tunnel 4.9: iPad (9th generation) (26.6, safari 26.6)

Exact qualified OS, browser, and kernel builds, per-lane evidence, and the qualifying candidate are recorded in docs/RELEASE_STATUS.md and docs/COMPATIBILITY.md at this source commit.

Required deployment preconditions

  • Install mainline OMP >=18.1.20 (source reference: v18.12.5 at d5cd750e41fede277f9eb933455da92a0738915e), set collab.autoStart to control or view, and start sessions with plain omp. No gateway integration patch is required.
  • Run Tailscale's TUN-mode client and Tailscale Serve over tailnet HTTPS. Userspace networking, Funnel, Portal Tunnel, and self-hosted or proxied relays are not supported.

Known environment limitation

Android Chrome can wedge its process-wide network state outside the qualified lock/Airplane/Doze transitions. Native EventSource reconnection and the bounded snapshot fallback recover the qualified cases; after an uninterrupted prolonged visible outage the loaded shell exposes force-stop/reopen help. The release does not claim page JavaScript can restart a failed browser process.
The Windows claim is start at interactive logon, not at boot. Background Web Push records force-stop and Doze outcomes as observed variants, never as guaranteed delivery.
Cloud-device clients are qualified in the browser: Tailscale Serve saw the qualification workstation's login, not the phone's own, and iPhone alerts were proven with the device unlocked, not on the lock screen.

Install or upgrade

For the first upgrade from the fork-era gateway, retain its signed archive and matching private configuration, then use that archive's uninstall command to stop and unregister its service. This leaves config and installed runtimes in place; an active fork-era service cannot authenticate with the new readiness token.
Extract omp-session-gateway-0.8.0-bun.tar, then run bun apps/gateway/src/cli.js install --origin https://host.tailnet.ts.net --allow user@example.com with the deployment's real values. Repeat --allow for additional identities. Subsequent mainline reinstalls preserve configuration and the readiness token.

Rollback

The selected predecessor is v0.7.7. Gateway rollback does not switch or restart the separately running OMP process. This release uses stock OMP v18.12.5. rollback --to selects only retained runtimes. Preserve configuration and readiness-token state; see docs/UPGRADE_ROLLBACK.md for predecessor compatibility and stopped-service recovery.