|
| 1 | +# Download Hosting |
| 2 | + |
| 3 | +## Public Paths |
| 4 | + |
| 5 | +```ts |
| 6 | +hex.kitlangton.dev // versioned links and platform requirements |
| 7 | +├── downloads.hex.kitlangton.dev // direct R2 Custom Domain; no redirect |
| 8 | +│ ├── releases/HEX-<version>-arm64.dmg |
| 9 | +│ ├── releases/HEX-<version>-arm64.zip // signed Sparkle artifact |
| 10 | +│ ├── releases/HEX-latest-arm64.dmg // mutable pointer; no-cache |
| 11 | +│ └── appcast.xml // mutable pointer; published last |
| 12 | +└── github.com/anomalyco/hex |
| 13 | + └── releases/download/app-v<version>/HEX-<version>-arm64.dmg |
| 14 | +``` |
| 15 | + |
| 16 | +The `hex-releases` bucket retains its existing `r2.dev` public endpoint so older |
| 17 | +Rust installations can still fetch the feed. The current appcast's enclosure |
| 18 | +URLs use the custom hostname. No legacy Swift feed is involved. |
| 19 | + |
| 20 | +The download hostname has active TLS with minimum TLS 1.2. A Cloudflare |
| 21 | +Configuration Rule disables **Browser Integrity Check** only for |
| 22 | +`http.host eq "downloads.hex.kitlangton.dev"`. This is public file hosting for |
| 23 | +browser and non-browser clients: the inherited zone check returned HTTP 403, |
| 24 | +error 1010, for Python's default user agent. The host-specific rule restored |
| 25 | +HTTP 200 without changing the zone-wide setting. Keep future browser challenges |
| 26 | +off download and updater routes. |
| 27 | + |
| 28 | +`scripts/release-app.sh publish` uploads and reads back the R2 DMG and ZIP, then |
| 29 | +calls `scripts/publish-app-mirror.sh`. The mirror starts as a draft, verifies |
| 30 | +the uploaded DMG, publishes with `--latest=false`, and verifies an unauthenticated |
| 31 | +download. Existing assets must match byte-for-byte; they are never clobbered. |
| 32 | +Only then does the publisher move the latest DMG and publish the appcast. |
| 33 | +App tags remain separate from TypeScript SDK tags; do not use GitHub's generic |
| 34 | +`releases/latest` redirect for an app download. |
| 35 | + |
| 36 | +After each macOS publication, update the site's `MAC_VERSION`, the README's |
| 37 | +explicit app mirror link, and `anomalyco/homebrew-tap/Casks/hex.rb`. Deploy the |
| 38 | +site using its checked-in Wrangler config and verify both rendered links. |
| 39 | + |
| 40 | +## Network Recovery |
| 41 | + |
| 42 | +App and model downloads have different hosts. Managed networks may need to allow: |
| 43 | + |
| 44 | +- `downloads.hex.kitlangton.dev` for app artifacts and feeds. |
| 45 | +- GitHub release downloads and their asset delivery host for the alternative DMG. |
| 46 | +- `huggingface.co` and its model download CDN for dictation-model setup. |
| 47 | +- `download.moonshine.ai` for optional Voice Commands. |
| 48 | + |
| 49 | +If the old update endpoint is blocked, install the new signed DMG manually. |
| 50 | +After restoring model-host access, retry preparation in Settings or choose |
| 51 | +Retry for Commands. Transfer failures preserve partial downloads. App download |
| 52 | +success does not establish model-host reachability, and our external checks do |
| 53 | +not establish access from a particular enterprise network. |
| 54 | + |
| 55 | +## Observed Migration Checks — September 11, 2026 |
| 56 | + |
| 57 | +- The initial 2.1.16 mirror and custom-domain DMG matched the published Homebrew |
| 58 | + SHA-256: `102dc1a8d80dc359ee15a30141957b6a311e581214b44a3c615026fa91288b8a`. |
| 59 | + Its notarization staple validated. |
| 60 | +- All five retained Sparkle ZIPs (2.1.12–2.1.16) were fetched directly through |
| 61 | + the custom domain, compared to the prepared artifacts, checked against the |
| 62 | + feed's lengths, and verified with the app's Ed25519 public key. |
| 63 | +- The migration changed only feed hostnames and terminal whitespace; versions, |
| 64 | + signatures, lengths, and release notes were preserved. The published feed was |
| 65 | + read back identically from both the custom host and old R2 endpoint. |
| 66 | +- The live website was rendered and inspected at 1280×900 and 390×844. Both |
| 67 | + showed the version, requirements, and alternate link. |
| 68 | +- Homebrew's cask and livecheck use the custom hostname; the 2.1.16 checksum |
| 69 | + stayed unchanged during the host migration. |
| 70 | +- `cargo test --locked`: 455 passed, 10 opt-in tests ignored, and all 12 keyboard |
| 71 | + layout child processes passed. A stale Homebrew `libgit2` build-cache path was |
| 72 | + cleared before the successful run. Strict all-target/all-feature Clippy and |
| 73 | + the site's TypeScript/production build passed. |
| 74 | +- No signed Linux feed has been published yet. Linux installer/updater source |
| 75 | + defaults were migrated; no Linux native install or enterprise-network test |
| 76 | + was performed as part of these hosting checks. |
0 commit comments