From c3b30ce4884aaba7aab3be60e0451e0b290e4575 Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Sun, 20 Sep 2026 05:54:22 -0700 Subject: [PATCH 1/4] docs: plan moq installer and public install URL Co-Authored-By: Codex --- quest/m2/README.md | 2 ++ quest/m2/moq-install-url.md | 34 +++++++++++++++++++++ quest/m2/moq-installer.md | 60 +++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 quest/m2/moq-install-url.md create mode 100644 quest/m2/moq-installer.md diff --git a/quest/m2/README.md b/quest/m2/README.md index 8b227e7be2..b558eb30c8 100644 --- a/quest/m2/README.md +++ b/quest/m2/README.md @@ -186,6 +186,8 @@ before format-specific metadata. Unrelated areas can proceed in parallel. - [#2907](/quest/m2/2907-bind-the-browser-through-moq-ffi-uniffi-instead-of-a.md) - Bind the browser through moq-ffi/UniFFI instead of a second hand-written wasm API - [#2850](/quest/m2/2850-js-net-give-reader-a-synchronous-decode-so-the-publisher.md) - js/net: decode messages synchronously from buffered bytes and delete the publisher read-ahead queue (dev) - [Cluster flags](/quest/m2/cluster-flags.md) - a discovery mechanism carries its own prerequisites, so an incomplete cluster config cannot be expressed +- [Install moq](/quest/m2/moq-installer.md) - one command installs or upgrades the released CLI on macOS and Linux +- [Install URL](/quest/m2/moq-install-url.md) - moq.dev serves the canonical installer at /install.sh - [`moq relay`](/quest/m2/moq-relay-subcommand.md) - the relay runs under a `moq` verb with its own flags and TOML, while `moq-relay` stays a minimal binary - [`moq` serves like a relay](/quest/m2/cli-serve.md) - a `moq --listen` session is authenticated, scoped, counted, and drained like a relay's; the relay is `moq` listening by default - [#3137](/quest/m2/3137-moqsrc-bound-the-pending-rendition-subscriptions-a.md) - moqsrc: bound the pending rendition subscriptions a catalog can open diff --git a/quest/m2/moq-install-url.md b/quest/m2/moq-install-url.md new file mode 100644 index 0000000000..a5416887fd --- /dev/null +++ b/quest/m2/moq-install-url.md @@ -0,0 +1,34 @@ +# [S] Publish the moq.dev install URL + +## Goal + +`curl -fsSL https://moq.dev/install.sh | bash` installs or upgrades `moq` +using the canonical installer from moq-dev/moq. The short URL works without +maintaining another copy of the install logic. + +## Plan + +- Implement the hosting change in **moq-dev/moq.dev**, which owns the root + website, not moq.pro. Track this cross-repository work here beside its + installer dependency; complete this quest only after the website change + and final documentation update have landed. +- Reuse the site's existing asset/Worker publishing path to expose the + canonical installer over HTTPS, preferably with a redirect to its published + source. If using a Worker redirect, include `/install.sh` in + `assets.run_worker_first` so a missing static asset cannot bypass the route. + Preserve non-success responses for unavailable scripts rather than serving + the site's HTML fallback. Keep redirect and cache behavior compatible with + updates to the canonical installer. +- Verify the route on `new.moq.dev` and test the complete redirected download. + Run the downloaded script in a temporary install directory and confirm + `moq --version`. Verify the public URL after an authorized production deploy; + this plan does not authorize a production deployment. +- Switch `doc/setup/install.md` in moq-dev/moq to the short URL once it is + working. Keep upgrade and version-selection examples aligned with the + canonical installer's interface. Add route coverage to the site's normal + checks for the shell response/redirect and error behavior. + +## Required + +- [Install moq](/quest/m2/moq-installer.md) - canonical installer, release + selection, upgrade behavior, and tests are published first diff --git a/quest/m2/moq-installer.md b/quest/m2/moq-installer.md new file mode 100644 index 0000000000..47e6cc4208 --- /dev/null +++ b/quest/m2/moq-installer.md @@ -0,0 +1,60 @@ +# [M] One-command moq installation and upgrades + +## Goal + +A canonical Bash installer installs the released `moq` binary on supported macOS and Linux machines without Rust or sudo. Running +it again upgrades the same installation; selecting a version supports +reproducible installs and deliberate downgrades. + +Install only `moq` from the `moq-cli` release. Token and relay functionality +belong to its subcommands, not separate installer choices. This work does +not implement those subcommands, automatic updates, a self-update command, +service setup, Windows support, or new release targets. + +## Plan + +- Default to the latest stable `moq-cli` release, with an explicit version + option. Resolve that product's tags, not the repository-wide latest + release: this repository publishes multiple independently versioned crates. + Refuse missing versions, malformed input, and incomplete releases clearly. +- Reuse the release archives and `SHA256SUMS`. Verify the selected archive + before extracting and installing its expected executable. Stage and check + the replacement before an atomic replacement on the destination filesystem; + download, verification, extraction, or validation failures leave an existing + installation usable. Clean up temporary files on failure or interruption. +- Support the existing targets: macOS ARM64 and Linux x86_64/ARM64 with + glibc 2.34 or newer. Refuse unsupported operating systems, architectures, + and libc variants with actionable diagnostics. Intel macOS and musl/Alpine + require separate release work. +- Default to `~/.local/bin` with an explicit directory override. Do not invoke + sudo or edit shell profiles. Print the installed version and path, and + shell-appropriate PATH instructions when needed. Detect when another + `moq` on PATH would take precedence so success does not imply the wrong + binary will run. Do not follow an existing destination symlink into a + package manager's installation or overwrite a conflicting unmanaged file. + Repeated installs must recognize and replace their own installation. +- Keep the canonical script and its tests in this repository. Publish a + usable HTTPS source for the dependent website quest; that quest exposes + `https://moq.dev/install.sh` without duplicating installer logic. +- Document first install, latest-version upgrade, explicit version selection, + directory override, PATH setup, and removal in `doc/setup/install.md`. + Use the working canonical URL until the website quest switches the example. + Package-manager installations continue to use their package manager for + upgrades. Describe only the subcommands the selected release actually ships. +- Wire installer tests into `just check` or `just test` and CI. Cover initial + install, repeat install, upgrade, explicit downgrade, product-specific latest + selection, unsupported hosts, corrupt/missing assets, destination conflicts, + and failure preserving an existing executable. Use controlled fixtures for + failure cases and native macOS/Linux smoke coverage for executable startup. + Exercise the canonical script with real release assets in a temporary + install directory and run the installed `moq --version`. The dependent + website quest owns verification of the final public URL. + +## Related + +- [Binary release workflow](/quest/m2/tooling/release-binary.md) - reuse its + artifacts without requiring workflow consolidation +- [`moq relay`](/quest/m2/moq-relay-subcommand.md) - relay functionality joins + the same executable independently of its installation method +- [Install URL](/quest/m2/moq-install-url.md) - exposes this installer through + the moq.dev website after it is published From 783910b71d5dc2d52a23a861ec87d602cf4add3c Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Sun, 20 Sep 2026 06:01:03 -0700 Subject: [PATCH 2/4] docs: clarify installer ownership checks Co-Authored-By: Codex --- quest/m2/moq-installer.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/quest/m2/moq-installer.md b/quest/m2/moq-installer.md index 47e6cc4208..859acd15bd 100644 --- a/quest/m2/moq-installer.md +++ b/quest/m2/moq-installer.md @@ -2,8 +2,9 @@ ## Goal -A canonical Bash installer installs the released `moq` binary on supported macOS and Linux machines without Rust or sudo. Running -it again upgrades the same installation; selecting a version supports +A canonical Bash installer installs the released `moq` binary on supported +macOS and Linux machines without Rust or sudo. Running it again upgrades +the same installation; selecting a version supports reproducible installs and deliberate downgrades. Install only `moq` from the `moq-cli` release. Token and relay functionality @@ -32,7 +33,11 @@ service setup, Windows support, or new release targets. `moq` on PATH would take precedence so success does not imply the wrong binary will run. Do not follow an existing destination symlink into a package manager's installation or overwrite a conflicting unmanaged file. - Repeated installs must recognize and replace their own installation. + Keep a durable ownership record bound to the destination and installed + binary digest. Refuse replacement when the record is missing, malformed, + or mismatched, including a record copied from another destination. A valid + prior installation can be replaced; failed upgrades must preserve both its + binary and usable ownership record. - Keep the canonical script and its tests in this repository. Publish a usable HTTPS source for the dependent website quest; that quest exposes `https://moq.dev/install.sh` without duplicating installer logic. From 9a87949ac2807acfc4ffd2c48f07ef53a66343be Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Sun, 20 Sep 2026 17:41:03 -0700 Subject: [PATCH 3/4] docs: define atomic installer recovery Require a journaled binary and ownership-record transaction, deterministic recovery or rollback, and failure tests at every commit boundary. Co-Authored-By: GPT-5 --- quest/m2/moq-installer.md | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/quest/m2/moq-installer.md b/quest/m2/moq-installer.md index 859acd15bd..f6229b1169 100644 --- a/quest/m2/moq-installer.md +++ b/quest/m2/moq-installer.md @@ -20,9 +20,20 @@ service setup, Windows support, or new release targets. Refuse missing versions, malformed input, and incomplete releases clearly. - Reuse the release archives and `SHA256SUMS`. Verify the selected archive before extracting and installing its expected executable. Stage and check - the replacement before an atomic replacement on the destination filesystem; - download, verification, extraction, or validation failures leave an existing - installation usable. Clean up temporary files on failure or interruption. + the replacement before modifying the destination. Commit the executable and + ownership record as one recoverable transaction on the destination + filesystem: stage the new pair, retain the validated prior pair, and write a + durable journal before either rename. On a handled failure, roll back both + files. After interruption, the next run must use the journal to complete the + new pair when both staged objects validate together or restore the prior pair; + it must not misclassify a partial transaction as an unmanaged installation. + Flush staged files, journal updates, renames, and their directory entries at + the required commit boundaries. Remove the journal and backups only after the + matching pair is durable. This is the atomic installation contract: recovery + exposes either the complete old pair or the complete new pair, never a mixed + pair. A failed initial install leaves no destination, while a failed upgrade + leaves the prior executable and ownership record usable. Clean up temporary + files after commit or rollback. - Support the existing targets: macOS ARM64 and Linux x86_64/ARM64 with glibc 2.34 or newer. Refuse unsupported operating systems, architectures, and libc variants with actionable diagnostics. Intel macOS and musl/Alpine @@ -50,7 +61,10 @@ service setup, Windows support, or new release targets. install, repeat install, upgrade, explicit downgrade, product-specific latest selection, unsupported hosts, corrupt/missing assets, destination conflicts, and failure preserving an existing executable. Use controlled fixtures for - failure cases and native macOS/Linux smoke coverage for executable startup. + failure cases, including interruption before and after every journal, rename, + durability, and cleanup boundary. Assert that each case completes the new + pair or restores the old pair, and that an initial-install failure leaves + neither file. Add native macOS/Linux smoke coverage for executable startup. Exercise the canonical script with real release assets in a temporary install directory and run the installed `moq --version`. The dependent website quest owns verification of the final public URL. From f70d6408a7520cac554ebbda61b511822631d92e Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Sun, 20 Sep 2026 18:36:14 -0700 Subject: [PATCH 4/4] docs: specify installer recovery phases Define the two rename phases, cleanup-only recovery after a complete commit, and the missing interruption regression. Co-Authored-By: GPT-5 --- quest/m2/moq-installer.md | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/quest/m2/moq-installer.md b/quest/m2/moq-installer.md index f6229b1169..3656af187f 100644 --- a/quest/m2/moq-installer.md +++ b/quest/m2/moq-installer.md @@ -23,10 +23,14 @@ service setup, Windows support, or new release targets. the replacement before modifying the destination. Commit the executable and ownership record as one recoverable transaction on the destination filesystem: stage the new pair, retain the validated prior pair, and write a - durable journal before either rename. On a handled failure, roll back both - files. After interruption, the next run must use the journal to complete the - new pair when both staged objects validate together or restore the prior pair; - it must not misclassify a partial transaction as an unmanaged installation. + durable journal before either rename. Record distinct phases after the + executable rename and after the ownership-record rename. On a handled + failure, roll back both files. After interruption, the next run must use the + journal to complete the new pair when both staged objects validate together. + If both renames completed, validate the installed pair and finish cleanup; + otherwise restore the prior pair, or remove every transaction file for an + initial install. Recovery must not misclassify a partial transaction as an + unmanaged installation. Flush staged files, journal updates, renames, and their directory entries at the required commit boundaries. Remove the journal and backups only after the matching pair is durable. This is the atomic installation contract: recovery @@ -62,9 +66,10 @@ service setup, Windows support, or new release targets. selection, unsupported hosts, corrupt/missing assets, destination conflicts, and failure preserving an existing executable. Use controlled fixtures for failure cases, including interruption before and after every journal, rename, - durability, and cleanup boundary. Assert that each case completes the new - pair or restores the old pair, and that an initial-install failure leaves - neither file. Add native macOS/Linux smoke coverage for executable startup. + durability, and cleanup boundary. Explicitly cover the post-second-rename, + pre-cleanup state. Assert that each case completes the new pair or restores + the old pair, and that an initial-install failure leaves neither file. Add + native macOS/Linux smoke coverage for executable startup. Exercise the canonical script with real release assets in a temporary install directory and run the installed `moq --version`. The dependent website quest owns verification of the final public URL.