diff --git a/installer/PLAN.md b/installer/PLAN.md index a096cfe..a0f9ec0 100644 --- a/installer/PLAN.md +++ b/installer/PLAN.md @@ -1,8 +1,17 @@ # Runic Gateway Installer โ€” plan -Status: **planning**. No installer code exists yet. This document is the design of record; it -supersedes the informal overview it grew out of, which described a ServUO integration that does not -match how `servuo-plugins` actually ships (see [Corrections](#corrections-to-the-original-overview)). +Status: **Phase 0 in progress.** No installer code exists yet. This document is the design of record; +it supersedes the informal overview it grew out of, which described a ServUO integration that does +not match how `servuo-plugins` actually ships (see +[Corrections](#corrections-to-the-original-overview)). + +| Phase 0 item | State | +|---|---| +| 0.1 `servuo-plugins` release workflow | ๐ŸŸจ In review โ€” [servuo-plugins#7](https://gitea.whitlocktech.com/RunicGateway/servuo-plugins/pulls/7) | +| 0.2 `link` installable (data paths + `--print-config`) | โฌœ Not started | +| 0.3 Bundle CI in the installer repo | โฌœ Not started | +| 0.4 This file + `INSTALL.md` | ๐ŸŸฆ This file exists; `INSTALL.md` waits on the shape settling | +| โ€” Repo bootstrap (governance + CI) | ๐ŸŸจ [`RunicGateway/installer`](https://gitea.whitlocktech.com/RunicGateway/installer) created; workflows in [installer#1](https://gitea.whitlocktech.com/RunicGateway/installer/pulls/1) | --- @@ -134,15 +143,16 @@ operators. ### 2.6 Prerequisites the overview assumed away -- **`servuo-plugins` has no release workflow.** Only `link` does. "Pull latest repository" is - replaced by a release tarball, which has to be built first (Phase 0). +- **`servuo-plugins` had no release workflow.** Only `link` did. "Pull latest repository" is replaced + by a release tarball, which had to be built first โ€” Phase 0 item 1, now in review + ([servuo-plugins#7](https://gitea.whitlocktech.com/RunicGateway/servuo-plugins/pulls/7)). - **arm64 is not buildable today.** `link/release.yml` cross-compiles only `x86_64-unknown-linux-gnu` and `x86_64-pc-windows-gnu`. An arm64 `.deb` needs another cross toolchain. -- **The compat matrix has no home.** `PROTOCOL_VERSION` currently lives only in - `link/sidecar/src/main.rs`. The sidecar publishes it via `X-UOLink-Version` and `/health`, and the - website stores an expected value โ€” but the *plugin's* protocol version is not queryable before - boot. See ยง7. +- **The compat matrix has no home.** `PROTOCOL_VERSION` lives in `link/sidecar/src/main.rs`. The + sidecar publishes it via `X-UOLink-Version` and `/health`, and the website stores an expected + value โ€” but the *plugin's* protocol version is not queryable before boot. Phase 0 item 1 gives it + a home: `servuo-plugins/overlay.toml`, declared into the overlay manifest. See ยง7.0 / ยง7.1. --- @@ -157,7 +167,7 @@ Runic Gateway Installer v1.0.0 โ”œโ”€โ”€ runicgateway-installer-linux-x86_64 โ””โ”€โ”€ SHA256SUMS -uo-link v3.x.y (existing release, extended) +uo-link v0.x.y (existing release, extended) โ”œโ”€โ”€ uo-link-sidecar-windows-x86_64.exe โ”œโ”€โ”€ uo-link-sidecar-linux-x86_64 โ”œโ”€โ”€ runicgateway-link__amd64.deb (Phase 5) @@ -222,6 +232,26 @@ Repo work that must land before an installer can exist. consume only `{version, changelog, artifacts}`). The adapter half produces `runicgateway-overlay-.tar.gz` containing `overlay/`, `patches/`, and a `manifest.json` (version, commit, per-file SHA256, declared protocol version, minimum ServUO version). + + As built ([servuo-plugins#7](https://gitea.whitlocktech.com/RunicGateway/servuo-plugins/pulls/7)), + with three deviations from `link`'s copy that each fell out of the repo rather than being chosen: + + - **No build gates, structural gates instead.** Nothing in that repo can be compiled without + ServUO reference assemblies, so CI asserts what it honestly can: `Bridge.cfg` and the Bridge + scripts present, `Scripts.csproj` present (its absence ships code that never compiles while + ServUO reports success โ€” ยง2.1), every `.patch` parseable via `git apply --stat`, and each + patch's companion `.cs` present. + - **No bump commit, so no push to `main`.** `link` writes the version into `Cargo.toml` because + the binary embeds it; the tarball embeds nothing but the generated manifest, so the tag *is* + the version. That workflow needs no branch-protection exception. + - **`overlay.toml` at the repo root** holds the declared `protocol` and the ServUO compatibility + values, read by CI into the manifest. It exists because the number needs one maintained home โ€” + see ยง7 for why the plugin cannot simply be asked. + + The tarball uses a **fixed** top-level directory, `runicgateway-overlay/`, not a versioned one: + the installer looks for `overlay/`, `patches/` and `manifest.json` at known paths rather than + parsing the version it is trying to read. Member order, mtime and ownership are pinned, so a + given tree yields a byte-identical tarball and its checksum moves only when its contents do. 2. **`link`: make the sidecar installable.** Confirm/settle default data paths, and add a way to read back config non-interactively (e.g. `--print-config` emitting JSON: bind addresses, token, protocol version, db path) so the installer does not have to scrape logs for the token. @@ -262,9 +292,9 @@ degrade loudly rather than silently. ``` โœ“ ServUO found /opt/ServUO (57.4) -โœ“ Overlay in sync 23 files, all hashes match install.json +โœ“ Overlay in sync 30 files, all hashes match install.json โš  Patch tier 1 of 3 applied โ€” vendor.sale unavailable -โœ“ uo-link installed 3.0.1 +โœ“ uo-link installed 0.3.0 โœ“ Service running, enabled โœ“ Sidecar reachable 127.0.0.1:8080 /health ok โœ“ Protocol sidecar 3 = overlay manifest 3 @@ -342,6 +372,41 @@ Three components version independently, bound by a protocol contract: - **plugin overlay** โ€” has no queryable version before ServUO boots. The overlay release `manifest.json` declares it, and `install.json` records what was deployed. +### 7.0 The overlay manifest + +Shipped inside every `runicgateway-overlay-.tar.gz`, generated by that repo's release workflow: + +```json +{ + "component": "servuo-plugins-overlay", + "version": "0.1.0", + "commit": "968b526โ€ฆ", + "repo": "RunicGateway/servuo-plugins", + "protocol": 3, + "servuo": { "min_version": "57.4", "patches_verified_against": "57.4" }, + "files": { "overlay/Config/Bridge.cfg": "32718424โ€ฆ", "patches/โ€ฆ": "โ€ฆ" } +} +``` + +`version` and `commit` come from the release engine; `protocol` and the `servuo` block are read from +`servuo-plugins/overlay.toml`; `files` is a SHA256 per shipped file. + +Two of these carry weight beyond documentation: + +- **`protocol` is a hand-maintained declaration, and has to be.** The plugin announces no version on + the wire and none is queryable before ServUO boots, so nothing in CI can derive it โ€” which makes + this line the only thing ยง7.1's gate 1 has to compare the sidecar against. The duty is stated in + `overlay.toml` and in that repo's README: **bump it in the same PR that changes the emitters**, the + way `link` bumps `PROTOCOL_VERSION`. +- **`files` is what makes `doctor` able to tell "the operator edited a deployed file" from "the + overlay moved on"** (ยง5, Phase 4). The installer copies these hashes into `install.json` at deploy + time; a later mismatch against *both* the manifest and `install.json` means upstream changed, a + mismatch against `install.json` alone means local edits. + +`min_version` and `patches_verified_against` are separate on purpose. The base overlay only *adds* +files and is expected to work broadly; the patch tier diffs stock ServUO files and is verified +against exactly one version (ยง2.2). + ### 7.1 The bundle manifest **The bundle is the compat matrix.** Rather than the installer hardcoding versions or blindly @@ -351,8 +416,8 @@ resolving "latest", CI publishes a small manifest naming an exact, checked combi { "bundle": "2026.08.01", "protocol": 3, - "link": { "version": "3.0.1", "sha256": "a91f..." }, - "overlay": { "version": "2.4.0", "commit": "a81f42c", "sha256": "7c3e..." } + "link": { "version": "0.3.0", "sha256": "a91f..." }, + "overlay": { "version": "0.1.0", "commit": "968b526", "sha256": "7c3e..." } } ``` @@ -372,7 +437,7 @@ Two gates run at compose time, both cheap and both worth it: | Trigger | Why | |---|---| | `link` publishes a release | Its release job `POST`s to the installer repo's workflow-dispatch endpoint as its final step. `link/.gitea/workflows/release.yml` already declares `workflow_dispatch: {}` and already holds a `write:repository` token | -| `servuo-plugins` publishes a release | Same, once Phase 0 gives it a release workflow | +| `servuo-plugins` publishes a release | Same. Phase 0 item 1 gave it the release workflow; the dispatch step is marked as a TODO in that workflow's header and lands with the bundle CI it would call (item 3) โ€” a step that `404`s on every release is worse than no step | | Nightly cron on the installer repo | Recomputes from whatever the latest releases actually are, so a missed or failed dispatch self-heals instead of silently pinning operators to a stale sidecar | `repository_dispatch` is deliberately avoided โ€” support for it is uncertain on this Gitea version, @@ -401,11 +466,12 @@ rather than being silently retriggered every night forever. ### 7.4 Open risk -The v3 cutover is mid-flight โ€” protocol work landed on `edge` branches with the `edge โ†’ main` -cutover still open across four repos. Until that lands, `main` and `edge` disagree about -`PROTOCOL_VERSION`, so the installer must not hardcode a version anywhere; it reads what the -artifacts declare, and ยง7.1's gate 1 is what stops a mismatched pair from being published as a -bundle. See `docs/link/v3.md`. +**Settled as of the v3 cutover.** Protocol work landed on `edge` branches and the `edge โ†’ main` +cutover has now merged, so `main` speaks protocol 3 consistently across the repos. The rule it +motivated stands regardless and is not a temporary measure: **the installer hardcodes no protocol +version anywhere.** It reads what the artifacts declare, and ยง7.1's gate 1 is what stops a +mismatched pair from being published as a bundle โ€” which is the mechanism that will matter at the +*next* protocol bump, not just this one. See `docs/link/v3.md`. --- @@ -421,12 +487,14 @@ bundle. See `docs/link/v3.md`. 3. **Co-location assumption** โ€” the shard dials out to the sidecar on loopback `127.0.0.1:7788`, so sidecar and ServUO must share a host. Should the installer support installing only uo-link on a different host, or hard-assume co-location? -4. **Branch targeting for the new repo** โ€” `link`, `website`, `servuo-plugins` and `docs` are - mid-cutover between `edge` and `main`. The installer repo starts clean on `main`; the Phase 0 - `servuo-plugins` release workflow needs a target branch decision. - Resolved and moved into ยง1 / ยง2.2 / ยง5: uninstall scope, and minimum ServUO version. +**Resolved โ€” branch targeting for the new repo** (was question 4). The v3 cutover landed: +`servuo-plugins#6` merged, so that repo's `main` and `edge` agree at protocol 3. The release +workflow targets `main`, and the installer repo starts clean on `main`. ยง7.4's caution still applies +in principle โ€” the installer hardcodes no protocol version, it reads what the artifacts declare โ€” +but the specific `edge`/`main` disagreement that motivated it is gone. + --- ## 9. Administrator experience