Turns Runic Gateway from a UO-specific platform into a game-agnostic one:
game-specific routes, tables, screens and nav leave the core website and
become an installable module. Operators install the base site, install the
module for their game, and restart -- they never build anything.
Verified against the working trees rather than written from the draft. The
draft's load-bearing assumptions that did not survive:
* one flat module route prefix cannot coexist with URL preservation, since
UO routes span three access tiers -- modules own a named slot per tier
* there is no server-side nav list, and navOverrides.js refuses to have one,
so nav registration is client-side
* the nav feature-gate mechanism is itself the shard visibility system
* there is no migration system to model a module runner on -- schema.sql is
replayed idempotently every boot, so modules ship fragments
* boot/shutdown holds eight UO call sites with no hook to receive them
* notificationStreams, pushDispatch and announceWorker are entangled, not moves
* six UO routes are nested under the core users resource
* the Discord bot has no UO logic at all
* the installer never contacts the website and its Bundle is hardcoded to
two components, so delivery is website-side
* routeManifest and swagger walk app.js with no DB, so modules mount
synchronously from the filesystem
* production is a prebuilt pull-only image and CSP forbids inline script,
which together decide how the client half loads
Ten decisions are recorded as settled in Part 3.
Co-Authored-By: Claude <noreply@anthropic.com>