Commit Graph

13 Commits

Author SHA1 Message Date
3f12e5f49c docs(installer): record Phase 2 as built — sidecar install and service
Phases 1 and 2 now live on the installer repo's `edge` branch, so PLAN.md's
status, the config-path section, and the operator guide all move with them.

PLAN.md
- Status: phases 1 and 2 built. The `edge -> main` cutover now follows Phase 3
  rather than Phase 2, because INSTALL.md §4 describes the patch tier as part of
  the run and a release that answers "not implemented" to all of it is the same
  half-capable binary that kept Phase 1 off `main`.
- §2.3: the service definition always pins the config path, but only Linux pins
  the database. On Windows config and data share a directory, so the sidecar's
  own anchoring rule already lands it correctly — and `sc.exe` offers no
  per-service environment, only a machine-wide one that every process inherits
  and that outlives an uninstall.
- New "Phase 2 as built" section: the virtual service account, the config
  lockdown and why its two halves straddle registration, `--verify` running no
  part of the sidecar half, the protocol check against the installed binary,
  `RUNICGATEWAY_STATE_DIR` relocating the binary and suppressing service
  registration, degrading to a printed recipe with no root/LocalSystem fallback,
  and the token never entering install.json.
- §8 question 1 (Windows service mechanism) resolved: `sc create`, as
  recommended — plus the service identity the recommendation did not anticipate.

INSTALL.md
- Status banner: what is built, and that the patch tier is the remaining gap.
- §2: the illustrated run matches the sidecar block the binary actually prints.
- §3: a table of how each platform pins config and database, the dedicated
  service account on both, and the fact that sidecar.toml's permissions are
  restricted because it holds the auth token.
- Appendix A4: the Windows recipe now matches what the installer does —
  `--config` in binPath (single-quoted so PowerShell keeps the inner quotes),
  `obj=` for the virtual account, the icacls lockdown before and grants after,
  and no machine-wide environment variables.
- Troubleshooting: a row for a run that could not register a service, and one
  for a service that starts and immediately stops.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-04 15:40:26 -05:00
4bdc764742 docs(installer): record Phase 1 as built
PLAN.md moves from "Phase 0 complete, no code exists" to "Phase 1 built, on
edge", and the Phase 1 section gains an "As built" block in the same shape as
the Phase 0 entries — covering the decisions that were not already settled by
the design: why the crate lands on `edge` instead of `main`, why the library
target is not named after the binary (Windows UAC installer detection makes
`cargo test` unrunnable under that name), the dependency choices that follow
from the MinGW cross-build, path-based rather than name-based shard-running
detection, reading ServUO's version from Server/AssemblyInfo.cs, and the two
rules the smoke test corrected — install.json recording a state rather than the
run's verb, and the Bridge.cfg keep comparing against the last hash deployed
rather than the last hash seen.

INSTALL.md gains the same status note and one troubleshooting row: Windows
elevates the binary on launch because its file name contains "install", which
is expected and needs no action beyond running from an elevated shell.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-04 14:58:46 -05:00
5a6cb58a33 docs(installer): review the patched region, not the whole-file hash
The patch tier refused on a whole-file hash mismatch, which is the wrong
question: the three patches touch three small regions of three large files, so
an operator who edited Logging.cs somewhere else entirely was handed a manual
patch job they did not need. Hand-modified shards are the norm, so that refusal
covered most of the audience.

Replace the single hash test with a four-rung ladder (PLAN §2.2.1), cheapest and
safest first:

  0  post-patch text already present  -> no-op, keeps re-runs idempotent
  1  whole file matches the pre-image -> apply verbatim
  2  file differs, patched region is still byte-identical -> apply at the
     matched offset
  3  anything else -> do not touch the file; print the hunk to apply by hand

Rung 2 needs no new metadata: a unified diff already carries the stock text of
the region it edits (context lines plus the '-' lines). Guardrails keep it from
becoming a fuzzy apply -- exact match with only CRLF/trailing-whitespace
normalisation, exactly one occurrence or it fails, line numbers advisory only,
and all-or-nothing per patch file so a half-patched EventSink.cs cannot happen.
install.json records which rung applied each patch, and doctor and uninstall
report it.

This retires the blanket 57.4-only version gate, so PLAN gains §2.2.2 to draw
the line the ladder does not: content matching is a mechanical guarantee about
where text lands, not a support commitment. 57.4 stays the only supported
version. A non-57.4 tree may attempt the tier, but unsupported, untested and not
guaranteed -- behind a loud banner, a prompt defaulted to no, and its own
--patches-unsupported-servuo flag, because a bare --patches can be hit by
accident in a copied script. The unsupported marker persists into install.json,
every later doctor run, and the uninstall report.

INSTALL.md gets the operator-facing half: a block-quoted warning naming the
silent-script-build failure mode, the updated prerequisite row, prompts and flag
table, and a sample run showing all three outcomes.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-04 14:17:33 -05:00
90459f2c49 docs(installer): mark Phase 0.4 merged in the status table
docs#87 landed; the row it added still said 'in review'. The status table is
the first thing anyone reads in this file, so a stale row there is worse than
no row.
2026-08-04 14:02:32 -05:00
2dbe4d8388 Merge branch 'main' into chore/sync-installer-tree 2026-08-04 17:15:57 +00:00
83bd4ec2d4 docs(installer): link the Phase 0.4 PR from the status table 2026-08-04 11:40:06 -05:00
5c8585fe75 docs(installer): add the operator install guide (Phase 0.4)
Closes the last Phase 0 item. INSTALL.md is written before the installer
binary on purpose: everything it installs is already released (0.1-0.3), so
the guide is not speculation about a tool that might exist - it is the
specification of what the run asks, where it writes, what it prints, and what
the operator does next.

It is useful today. Appendix A is the same deployment done by hand - bundle
fetch, tarball verify and overlay copy, the optional patch tier,
--print-config provisioning, systemd unit / sc create - composed from the
released artifacts' actual contents and the sidecar's config and CLI source.
That appendix doubles as Phase 1's acceptance test.

Writing it settled four things the plan had left implicit, now recorded in
PLAN.md:

- The installer does not install itself; day-two commands run from the
  downloaded binary.
- The flag surface: --servuo, --patches/--no-patches, --host, --site-url and
  --yes join the --verify/--bundle/--purge the plan already named, so every
  prompt has a non-interactive equivalent.
- A modified Config/Bridge.cfg is reported, not overwritten - one deliberate
  deviation from deploy.ps1, whose overwrite-on-hash-differs rule is right for
  a developer and would silently revert an operator's whole shard config on
  update. install.json's recorded hashes are what make the distinction
  possible.
- Remote-website deployments: widen [web] bind, firewall it to the site's
  address, front it with TLS or a VPN off a trusted network. [shard] bind
  stays on loopback because that socket carries commands into the game.

Also adds the missing installer/ section to the docs index, and refreshes two
stale examples in PLAN.md (overlay file count, sidecar version).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-04 11:39:02 -05:00
runic-docs-bot
a6b20cb273 docs(tree): sync installer/PROJECT_TREE.md from RunicGateway/installer@0e7d5f3 [skip ci] 2026-08-04 16:19:51 +00:00
10ebce706f docs(installer): record Phase 0.3 — the bundle CI and where bundles live
Documentation half of installer Phase 0.3. Code PRs: RunicGateway/installer#3,
RunicGateway/link#25, RunicGateway/servuo-plugins#9.

Phase 0 item 3 asked for a compose job, a nightly cron, and a dispatch step in
each component. All three landed, and building them settled questions §7 had
left open — so those sections are corrected rather than appended to.

Status: Phase 0 is now all but complete. 0.2 is merged and released as link
v1.1.0; 0.3 is in review; 0.4 (INSTALL.md) is the remaining item, and the shape
it was waiting on has settled.

Phase 0 item 3 gains an "As built" subsection matching items 1 and 2, recording
what was chosen rather than inherited: why gate 1 reads the sidecar's protocol
from source at the release tag instead of asking the binary via --print-config
(it only answers for v1.1.0+, and --bundle <tag> must be able to recompose an
older pair); why gate 2 records the hash CI computed itself and separately
checks for assets absent from SHA256SUMS; why release metadata is read
anonymously; why an unrecognized asset name is a hard failure; and why a run
that changes nothing writes nothing.

§7.1 is corrected in two places. The manifest shape now shows link.assets as a
map keyed by platform — the single sha256 this section sketched could only ever
have described one of the two binaries link publishes — plus schema/generated
and the servuo block. And it gains a subsection naming where bundles are
published: committed under bundles/ in the installer repo, NOT one Gitea release
per bundle, because that repo's own releases are the installer binaries and
/releases/latest returns whichever release is newest regardless of kind.

§7.2 records that the dispatch steps now exist, and that a failed dispatch is a
warning rather than a failed release — which is what keeps the installer repo's
token out of the components' hard requirements.

§7.3 records that the releasable-commit rule must also exclude merge commits,
whose subject quotes the real one: without that, merging a docs: branch whose
title mentions a fix: would re-dispatch a declining release workflow nightly.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-04 11:17:28 -05:00
c1957f0bfb docs(installer): record Phase 0.2 — the sidecar's CLI and settled data paths
Phase 0.2 landed in link#24: the sidecar gained a four-flag CLI, --print-config,
and config-anchored data paths. Three sections of the installer plan asserted
facts that change as a result, so they are corrected rather than appended to.

- Status table: 0.1 merged (servuo-plugins#7/#8, overlay v0.1.1 released), 0.2 in
  review, repo bootstrap merged. 0.3 (bundle CI) is next and now unblocked — both
  components it composes exist.
- Phase 0 item 2 gains an "As built" subsection matching item 1's: why four
  hand-rolled flags rather than a parsing crate, why --print-config provisions
  instead of only reporting, why config_created/token_generated exist, and why no
  platform data directories are compiled into the binary.
- §2.3 (working-directory trap): half-closed in the sidecar — a relative
  [store].path now anchors to the config file's directory — while the service
  definitions still pin both env vars, and why that is not redundant.
- §2.4 (token handoff): the installer reads the handoff block out of one
  --print-config call and never parses the log, which is not a contract.
- §5 Phase 2 / Phase 4, §6: the ordering that follows (print-config before service
  registration), which doctor rows the CLI answers, that only the host is
  substituted into the printed URLs because web.bind is often 0.0.0.0, and that the
  printed token must not reach a log or support bundle.
- link/INTEGRATION.md §1: how to read the token back, replacing "the sidecar logs
  it" with the supported command and its output.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-04 10:48:44 -05:00
f0975df598 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>
2026-08-04 09:28:23 -05:00
25a5734107 docs(installer): add release orchestration and the bundle manifest
The installer needs CI that reacts when a component publishes a release. Adds
that as section 7, folded into version tracking because the bundle IS the compat
matrix -- which closes the "where does the compat matrix live" gap section 7
previously left open.

- 7.1 Bundle manifest: CI publishes an exact, protocol-checked combination of
  component versions; the installer resolves against it at run time and
  --bundle <tag> pins one. A link release regenerates JSON and leaves the
  installer binary untouched, so operators don't re-download the installer for a
  sidecar patch and the repo doesn't accumulate releases with identical code.
  Two compose-time gates: sidecar PROTOCOL_VERSION must equal the overlay
  manifest's declared version, and every asset's SHA256 must match.
- 7.2 Triggers: each component's release job POSTs to the installer's
  workflow-dispatch endpoint (link's release.yml already declares
  workflow_dispatch and already holds a write:repository token), plus a nightly
  cron so a missed dispatch self-heals. repository_dispatch avoided -- support
  is uncertain on this Gitea version.
- 7.3 Stale overlay: dispatch, don't wait. Components self-release on merge to
  their own main, so the release normally already exists. If main is ahead with
  *releasable* commits (docs:/chore: correctly cut nothing), fire that repo's
  workflow, compose from what exists now, warn loudly, and let the nightly fold
  in the result. Dispatching another repo's workflow is fine -- it still runs
  its own gates -- but polling it is not, since Gitea's dispatch endpoint
  returns no run handle.

Bundle CI becomes a Phase 0 deliverable, since Phase 1 resolves what to install
from the bundle. `update` now moves between checked combinations rather than two
independently-latest artifacts.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-01 06:11:08 -05:00
29056ba996 docs(installer): plan the Runic Gateway installer
Design of record for a deployment tool that takes a stock ServUO install and
configures it for Runic Gateway. Supersedes the informal overview it grew from,
which described a ServUO integration that does not match how servuo-plugins
actually ships.

Corrections that change the design:

- There is no RunicGateway.dll and no Plugins/ dir. The plugin ships as C#
  source compiled by ServUO at boot, so the step is a hash-compare sync of
  overlay/ -- but a successful copy does not mean a working bridge, because
  ScriptCompiler.Compile() ignores dotnet build's exit code and reloads the
  stale Scripts.dll.
- Stock ServUO files ARE modified, by three diffs in patches/. Made an opt-in,
  skippable tier: git apply against a hand-modified shard will fail, and the
  EventSink.cs patch needs a full core solution rebuild.
- Config paths collided with what the sidecar actually reads. Split ownership:
  sidecar.toml stays the sidecar's schema, install.json is the installer's.
  Service definitions pin UOLINK_CONFIG and UOLINK_DB_PATH, since the sidecar
  writes relative to CWD and would land in VirtualStore under Program Files.
- The token handoff was missing entirely -- the largest "installed it and
  nothing happened" failure mode.
- deploy.ps1 cannot be the cross-platform deployer; it stays the developer tool.

Decisions: public audience, unsigned binaries anchored on SHA256SUMS, Rust,
release-tarball plugin distribution, printed token handoff, new installer repo,
warn-and-skip on non-57.4 ServUO, and an uninstall that never edits the shard
tree -- it prints the files to delete and the hunks to revert.

Phases 0-5, with Phase 0 (a release workflow for servuo-plugins, which has
none today) gating everything else. Two open questions remain in section 8.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-01 05:44:44 -05:00