docs(installer): record Phase 0 progress and the overlay manifest
Tracks what actually landed while starting the installer plan, and corrects
the parts of the plan that the work proved wrong or stale.
Progress:
A Phase 0 status table at the top, so the plan says where it is rather
than needing a reader to reconstruct it from PR links.
Phase 0 item 1 (§5) now records the release workflow as built, including
its three deviations from link's copy — structural gates instead of build
gates, no bump commit and therefore no push to main, and overlay.toml as
the home for the declared protocol version. Plus the fixed tarball prefix
and why: the installer would otherwise have to parse the version it is
trying to read.
New §7.0 documents the overlay manifest as generated, and states plainly the
two things about it that carry weight: `protocol` is hand-maintained and has
to be (nothing in CI can derive it, which is exactly why §7.1's gate 1 has
something to compare), and `files` is what lets `doctor` distinguish
"operator edited a deployed file" from "the overlay moved on".
Corrections:
§2.6 the plugin's protocol version now has a home (overlay.toml), and
servuo-plugins now has a release workflow.
§7.2 the dispatch step is deliberately deferred to Phase 0 item 3.
§7.4 no longer "open risk" — the v3 cutover merged. The rule it motivated
(never hardcode a protocol version) is restated as permanent rather
than as a workaround for a mid-flight cutover.
§8 open question 4 (branch targeting) resolved: servuo-plugins#6 merged,
main == edge, everything targets main.
Version examples in §3, §5 and §7.1 said uo-link v3.x.y / 3.0.1, conflating
the release version with the protocol version. link is actually at v0.3.0 —
the two are independent, and the bundle names release versions, so an example
implying they track each other is actively misleading. Now uses the real
values (link 0.3.0, overlay 0.1.0, 30 overlay files).
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -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_<ver>_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-<ver>.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-<ver>.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
|
||||
|
||||
Reference in New Issue
Block a user