From 0fd6b91f22adeb5e943d9487a7bdcf352e7c96fd Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 18 Jul 2026 00:08:34 -0500 Subject: [PATCH] docs: move docs to RunicGateway/docs, repoint all references Extracted docs/ (ADMIN_CONTROLS, INTEGRATION, PLAN, PROTOCOL_2, RESEARCH, SHARD_PREREQS) into the central RunicGateway/docs repo under link/, with full commit history preserved via git filter-repo. The source cites these design docs by section throughout, so every in-repo reference (C# + Rust comments, Bridge.cfg, and the READMEs) is repointed at the new docs-repo URL. README references are rendered as markdown links; a Documentation pointer section is added to the top-level README. Docs repo: https://gitea.whitlocktech.com/RunicGateway/docs --- overlay/Config/Bridge.cfg | 6 +++--- overlay/Scripts/Custom/Bridge/BridgeAccountLink.cs | 2 +- overlay/Scripts/Custom/Bridge/BridgeAccounts.cs | 4 ++-- overlay/Scripts/Custom/Bridge/BridgeAdmin.cs | 4 ++-- overlay/Scripts/Custom/Bridge/BridgeConfig.cs | 8 ++++---- overlay/Scripts/Custom/Bridge/BridgeGovernance.cs | 2 +- overlay/Scripts/Custom/Bridge/BridgeHousing.cs | 2 +- overlay/Scripts/Custom/Bridge/BridgeJson.cs | 2 +- overlay/Scripts/Custom/Bridge/BridgeNews.cs | 2 +- overlay/Scripts/Custom/Bridge/BridgePresence.cs | 2 +- overlay/Scripts/Custom/Bridge/BridgeProfile.cs | 6 +++--- overlay/Scripts/Custom/Bridge/BridgeSocial.cs | 2 +- overlay/Scripts/Custom/Bridge/BridgeSweeps.cs | 2 +- patches/BridgeModerationAudit.cs | 2 +- patches/README.md | 4 ++-- tools/scaffolding/README.md | 2 +- 16 files changed, 26 insertions(+), 26 deletions(-) diff --git a/overlay/Config/Bridge.cfg b/overlay/Config/Bridge.cfg index 7a5ef92..ef09957 100644 --- a/overlay/Config/Bridge.cfg +++ b/overlay/Config/Bridge.cfg @@ -14,7 +14,7 @@ Port=7788 QueueCap=10000 # Sweep intervals, seconds. Measured on a 150-character shard: a vitals sweep costs -# 0.0015 ms/char, so 1000 online players is ~1.5 ms per sweep. See docs/PLAN.md §1. +# 0.0015 ms/char, so 1000 online players is ~1.5 ms per sweep. See https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/link/PLAN.md §1. StatSweepSeconds=30 DecaySweepSeconds=60 EconomySweepSeconds=300 @@ -29,7 +29,7 @@ ChampSweepSeconds=10 # support queue; the full open queue is also available on demand via pages.snapshot. PageSweepSeconds=5 -# Guild roster poll (docs/PROTOCOL_2.md Part B). Guilds expose only EventSink.JoinGuild, so +# Guild roster poll (https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/link/PROTOCOL_2.md Part B). Guilds expose only EventSink.JoinGuild, so # create/disband/leave/leader/alliance changes are found by diffing BaseGuild.List on this # interval (emit guild.update / guild.remove). Guild membership moves slowly; 60s is ample. GuildSweepSeconds=60 @@ -85,7 +85,7 @@ AdminReasonMaxLength=400 # Clamp on a timed ban's duration, seconds. A ban with no/zero duration is indefinite. AdminBanMaxDurationSec=31536000 -# Account provisioning (docs/PROTOCOL_2.md Part A). Which side may mint game accounts: +# Account provisioning (https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/link/PROTOCOL_2.md Part A). Which side may mint game accounts: # website — the website is the authority; pair with Accounts.AutoCreateAccounts=false # (else an in-game login of any new name still mints an account). # game — the game server is the authority; website account.create is refused. diff --git a/overlay/Scripts/Custom/Bridge/BridgeAccountLink.cs b/overlay/Scripts/Custom/Bridge/BridgeAccountLink.cs index 5e0b1ef..24f98ed 100644 --- a/overlay/Scripts/Custom/Bridge/BridgeAccountLink.cs +++ b/overlay/Scripts/Custom/Bridge/BridgeAccountLink.cs @@ -18,7 +18,7 @@ namespace Server.Custom.Bridge /// and replies link.ok. The tag persists to accounts.xml across restarts. /// /// The code table and the account write both live on the Core thread. The websiteUserId in - /// link.confirm is trusted only because the socket is loopback-only (docs/PLAN.md §2); if the + /// link.confirm is trusted only because the socket is loopback-only (https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/link/PLAN.md §2); if the /// sidecar ever moves off-host, gate it behind a shared secret. /// public static class BridgeAccountLink diff --git a/overlay/Scripts/Custom/Bridge/BridgeAccounts.cs b/overlay/Scripts/Custom/Bridge/BridgeAccounts.cs index e076eab..ef414e2 100644 --- a/overlay/Scripts/Custom/Bridge/BridgeAccounts.cs +++ b/overlay/Scripts/Custom/Bridge/BridgeAccounts.cs @@ -8,7 +8,7 @@ using Server.Misc; namespace Server.Custom.Bridge { /// - /// The account provisioning plane (docs/PROTOCOL_2.md Part A): website-driven account + /// The account provisioning plane (https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/link/PROTOCOL_2.md Part A): website-driven account /// creation and unlinking. Companion to BridgeAccountLink (the in-game [link flow), which /// is unchanged. /// @@ -18,7 +18,7 @@ namespace Server.Custom.Bridge /// Both handlers run on the Core thread (BridgeBoot marshals inbound lines through /// Timer.DelayCall first), so they touch accounts freely. /// - /// Trust model matches the admin plane (docs/ADMIN_CONTROLS.md §5): authorization lives on + /// Trust model matches the admin plane (https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/link/ADMIN_CONTROLS.md §5): authorization lives on /// the website; the shard trusts the loopback + token socket and a required "actor" field. /// The one shard-side floor on unlink is BridgeAdmin.Protected — a protected staff account is /// never unlinkable from the web. The whole create plane is opt-in via SignupMode / diff --git a/overlay/Scripts/Custom/Bridge/BridgeAdmin.cs b/overlay/Scripts/Custom/Bridge/BridgeAdmin.cs index b82d893..28ea0ef 100644 --- a/overlay/Scripts/Custom/Bridge/BridgeAdmin.cs +++ b/overlay/Scripts/Custom/Bridge/BridgeAdmin.cs @@ -13,7 +13,7 @@ namespace Server.Custom.Bridge /// Every handler runs on the Core thread (BridgeBoot marshals inbound lines through /// Timer.DelayCall first), so they may touch accounts, mobiles, and the network freely. /// - /// Trust model (docs/ADMIN_CONTROLS.md §5): authorization is enforced on the *website* — + /// Trust model (https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/link/ADMIN_CONTROLS.md §5): authorization is enforced on the *website* — /// these commands are gated there behind admin/moderator roles. The shard trusts the /// loopback socket exactly as town-crier does, and applies inbound commands with an implicit /// CoOwner authority. Its one hard floor is : a command refuses any @@ -248,7 +248,7 @@ namespace Server.Custom.Bridge /// Opens an admin.audit frame (origin=web) with the common fields. Broadcast to every /// connected dashboard so the website's moderation log stays complete regardless of which /// client issued the action. The in-game counterpart (origin=in-game) is emitted from - /// BridgeEvents; see docs/ADMIN_CONTROLS.md §5.5. + /// BridgeEvents; see https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/link/ADMIN_CONTROLS.md §5.5. /// private static System.Text.StringBuilder AuditBegin(string action, string actor, string target) { diff --git a/overlay/Scripts/Custom/Bridge/BridgeConfig.cs b/overlay/Scripts/Custom/Bridge/BridgeConfig.cs index 4ddd13e..21907ce 100644 --- a/overlay/Scripts/Custom/Bridge/BridgeConfig.cs +++ b/overlay/Scripts/Custom/Bridge/BridgeConfig.cs @@ -5,7 +5,7 @@ namespace Server.Custom.Bridge /// /// Which side may mint game accounts. Governs the bridge's inbound account.create verb; /// the in-game first-login auto-create is a separate core setting (Accounts.AutoCreateAccounts) - /// the operator pairs with this (docs/PROTOCOL_2.md §2). + /// the operator pairs with this (https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/link/PROTOCOL_2.md §2). /// public enum SignupMode { @@ -43,7 +43,7 @@ namespace Server.Custom.Bridge public static int TownCrierMaxActive { get; private set; } public static int TownCrierMaxDurationSec { get; private set; } - // Town Cryer news gump (docs/PROTOCOL_2.md §16). + // Town Cryer news gump (https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/link/PROTOCOL_2.md §16). public static int NewsMaxTitleLength { get; private set; } public static int NewsMaxBodyLength { get; private set; } public static int NewsMaxExternal { get; private set; } @@ -55,7 +55,7 @@ namespace Server.Custom.Bridge public static int AdminReasonMaxLength { get; private set; } public static int AdminBanMaxDurationSec { get; private set; } - // ---- account provisioning (docs/PROTOCOL_2.md Part A) ---- + // ---- account provisioning (https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/link/PROTOCOL_2.md Part A) ---- public static SignupMode Signup { get; private set; } public static bool AccountCreateEnabled { get; private set; } public static bool RequireIpForCreate { get; private set; } @@ -89,7 +89,7 @@ namespace Server.Custom.Bridge if (ChampSweepSeconds < 1) ChampSweepSeconds = 1; - // Social/political sweeps (docs/PROTOCOL_2.md Part B). Both change slowly, so the + // Social/political sweeps (https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/link/PROTOCOL_2.md Part B). Both change slowly, so the // defaults are unhurried; the pass is a handful of field reads over a small set. GuildSweepSeconds = Config.Get("Bridge.GuildSweepSeconds", 60); if (GuildSweepSeconds < 1) diff --git a/overlay/Scripts/Custom/Bridge/BridgeGovernance.cs b/overlay/Scripts/Custom/Bridge/BridgeGovernance.cs index c2b33b6..c2858f0 100644 --- a/overlay/Scripts/Custom/Bridge/BridgeGovernance.cs +++ b/overlay/Scripts/Custom/Bridge/BridgeGovernance.cs @@ -6,7 +6,7 @@ using Server.Engines.CityLoyalty; namespace Server.Custom.Bridge { /// - /// The town-governor stream (docs/PROTOCOL_2.md §10.2). In modern ServUO the "mayor of a + /// The town-governor stream (https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/link/PROTOCOL_2.md §10.2). In modern ServUO the "mayor of a /// town" is the Governor in the City Loyalty System (King Blackthorn's governance): each of /// the governed cities has a Governor, a GovernorElect, and an Election. None of these raises /// an EventSink, so — like and — the set diff --git a/overlay/Scripts/Custom/Bridge/BridgeHousing.cs b/overlay/Scripts/Custom/Bridge/BridgeHousing.cs index bca9d1c..31fe51a 100644 --- a/overlay/Scripts/Custom/Bridge/BridgeHousing.cs +++ b/overlay/Scripts/Custom/Bridge/BridgeHousing.cs @@ -7,7 +7,7 @@ using Server.Multis; namespace Server.Custom.Bridge { /// - /// The housing registry (docs/PROTOCOL_2.md §11 #9). BridgeSweeps already emits house.decay + /// The housing registry (https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/link/PROTOCOL_2.md §11 #9). BridgeSweeps already emits house.decay /// *transitions*; this is the complementary *board*: one row per house with owner, location, /// region, co-owners, value, and current decay level, so the website can render an owner→houses /// map. Like the other Part B boards it is a diff sweep over BaseHouse.AllHouses — emit diff --git a/overlay/Scripts/Custom/Bridge/BridgeJson.cs b/overlay/Scripts/Custom/Bridge/BridgeJson.cs index 1b19135..9d73789 100644 --- a/overlay/Scripts/Custom/Bridge/BridgeJson.cs +++ b/overlay/Scripts/Custom/Bridge/BridgeJson.cs @@ -8,7 +8,7 @@ namespace Server.Custom.Bridge { /// /// Outbound JSON is written by hand into a StringBuilder. It runs on the Core thread for - /// every emitted event, and the measured budget in docs/PLAN.md assumes this cost, not a + /// every emitted event, and the measured budget in https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/link/PLAN.md assumes this cost, not a /// reflection serializer's. /// /// Inbound JSON is parsed with JavaScriptSerializer. Commands arrive at human rates, so diff --git a/overlay/Scripts/Custom/Bridge/BridgeNews.cs b/overlay/Scripts/Custom/Bridge/BridgeNews.cs index c766406..294d35d 100644 --- a/overlay/Scripts/Custom/Bridge/BridgeNews.cs +++ b/overlay/Scripts/Custom/Bridge/BridgeNews.cs @@ -8,7 +8,7 @@ namespace Server.Custom.Bridge { /// /// Website news articles pushed into the modern Town Cryer News gump - /// (docs/PROTOCOL_2.md §16). Distinct from BridgeTownCrier, which drives the scrolling-crier + /// (https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/link/PROTOCOL_2.md §16). Distinct from BridgeTownCrier, which drives the scrolling-crier /// announcement lines (GlobalTownCrierEntryList). Here the full article — title, body (HTML), /// image, and a "more info" URL — becomes a TownCryerNewsEntry in TownCryerSystem.NewsEntries, /// which the stock news gumps already render (they branch on TextDefinition.Number, so string diff --git a/overlay/Scripts/Custom/Bridge/BridgePresence.cs b/overlay/Scripts/Custom/Bridge/BridgePresence.cs index d0a50f9..e164c2b 100644 --- a/overlay/Scripts/Custom/Bridge/BridgePresence.cs +++ b/overlay/Scripts/Custom/Bridge/BridgePresence.cs @@ -6,7 +6,7 @@ using Server.Mobiles; namespace Server.Custom.Bridge { /// - /// The presence stream (docs/PROTOCOL_2.md §11 #1/#2): who is online and where. Two parts: + /// The presence stream (https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/link/PROTOCOL_2.md §11 #1/#2): who is online and where. Two parts: /// /// presence.online - a periodic population snapshot (total, per-facet, per-region), emitted /// on a sweep but only when it changes, so the site has a live "N online" diff --git a/overlay/Scripts/Custom/Bridge/BridgeProfile.cs b/overlay/Scripts/Custom/Bridge/BridgeProfile.cs index 4e08ede..dd3a30b 100644 --- a/overlay/Scripts/Custom/Bridge/BridgeProfile.cs +++ b/overlay/Scripts/Custom/Bridge/BridgeProfile.cs @@ -15,7 +15,7 @@ namespace Server.Custom.Bridge /// /// A profile is the single most expensive read in the bridge (~0.07 ms + ~2.4 KB at the /// seeded scale, more for a fully-kitted character), so it is built on demand only, never in - /// a sweep. See docs/PLAN.md §1. + /// a sweep. See https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/link/PLAN.md §1. /// public static class BridgeProfile { @@ -83,7 +83,7 @@ namespace Server.Custom.Bridge } sb.Append(']'); - // worn equipment only — not the backpack/bank (see docs/PLAN.md §IV.4) + // worn equipment only — not the backpack/bank (see https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/link/PLAN.md §IV.4) sb.Append(",\"equipment\":["); first = true; foreach (var item in m.Items) @@ -104,7 +104,7 @@ namespace Server.Custom.Bridge } /// - /// The titles a character holds (docs/PROTOCOL_2.md §10.3). `selected` is the index into + /// The titles a character holds (https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/link/PROTOCOL_2.md §10.3). `selected` is the index into /// `reward` currently displayed (-1 if none). `fameKarma` and `skill` are the computed /// display titles (may be absent). `reward` is the raw reward-title list — an entry may be /// a cliloc number (as a string) or a literal string; resolve clilocs website-side. diff --git a/overlay/Scripts/Custom/Bridge/BridgeSocial.cs b/overlay/Scripts/Custom/Bridge/BridgeSocial.cs index 2bd1b1b..48b756d 100644 --- a/overlay/Scripts/Custom/Bridge/BridgeSocial.cs +++ b/overlay/Scripts/Custom/Bridge/BridgeSocial.cs @@ -7,7 +7,7 @@ using Server.Guilds; namespace Server.Custom.Bridge { /// - /// The guild stream (docs/PROTOCOL_2.md §10.1). Guilds have almost no useful EventSink: + /// The guild stream (https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/link/PROTOCOL_2.md §10.1). Guilds have almost no useful EventSink: /// EventSink.CreateGuild is only the load-time deserialization factory (Server/World.cs), and /// leave/disband/leader/alliance changes raise nothing. Only EventSink.JoinGuild is real. So, /// exactly like , the roster is polled: enumerate BaseGuild.List each diff --git a/overlay/Scripts/Custom/Bridge/BridgeSweeps.cs b/overlay/Scripts/Custom/Bridge/BridgeSweeps.cs index 9630ee2..0de3fb0 100644 --- a/overlay/Scripts/Custom/Bridge/BridgeSweeps.cs +++ b/overlay/Scripts/Custom/Bridge/BridgeSweeps.cs @@ -11,7 +11,7 @@ namespace Server.Custom.Bridge /// /// The three polled streams, for state that has no EventSink: player vitals, house decay, /// and money supply. All three run on the Core thread via repeating Timers, and the - /// measured cost (docs/PLAN.md §1) is why they can: at the seeded scale a full pass of all + /// measured cost (https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/link/PLAN.md §1) is why they can: at the seeded scale a full pass of all /// three is well under a millisecond. /// /// Timers do not fire during a world save (Timer.cs:322), so a sweep that would have landed diff --git a/patches/BridgeModerationAudit.cs b/patches/BridgeModerationAudit.cs index 2b5c686..9565816 100644 --- a/patches/BridgeModerationAudit.cs +++ b/patches/BridgeModerationAudit.cs @@ -9,7 +9,7 @@ namespace Server.Custom.Bridge /// /// Forwards IN-GAME uses of the write-plane verbs to the website as admin.audit /// (origin=in-game), so the site's moderation log is complete regardless of whether an action - /// came from the website or a staff member in the game client. See docs/ADMIN_CONTROLS.md §5.5. + /// came from the website or a staff member in the game client. See https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/link/ADMIN_CONTROLS.md §5.5. /// /// Two sources, mirroring how the shard records each: /// - ban / kick: resolved with their target inside the stock generic command, which logs a diff --git a/patches/README.md b/patches/README.md index d59b8b0..070d6bc 100644 --- a/patches/README.md +++ b/patches/README.md @@ -11,7 +11,7 @@ git apply patches/.patch ## Phase 7 — player-vendor sale (a coupled unit) -Player-vendor purchases raise **no** EventSink. `ValidVendorPurchase` / `ValidVendorSell` cover NPC vendors only. The commit point is `PlayerVendorBuyGump.OnResponse`, the only place where buyer, vendor **owner**, price, and commission are all in scope — exactly what cheat detection needs. See `docs/PLAN.md` §6. +Player-vendor purchases raise **no** EventSink. `ValidVendorPurchase` / `ValidVendorSell` cover NPC vendors only. The commit point is `PlayerVendorBuyGump.OnResponse`, the only place where buyer, vendor **owner**, price, and commission are all in scope — exactly what cheat detection needs. See [PLAN.md](https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/link/PLAN.md) §6. This is the one non-drop-in piece. Apply all three together: @@ -56,4 +56,4 @@ Phase 0 modifies an existing file but ships as a whole-file overlay (`overlay/Sc ## Note on shard repairs -The deletions and edits described in `docs/SHARD_PREREQS.md` are one-time repairs to a specific broken install, not part of the bridge. They are not shipped here. +The deletions and edits described in [SHARD_PREREQS.md](https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/link/SHARD_PREREQS.md) are one-time repairs to a specific broken install, not part of the bridge. They are not shipped here. diff --git a/tools/scaffolding/README.md b/tools/scaffolding/README.md index f548e30..e5d0688 100644 --- a/tools/scaffolding/README.md +++ b/tools/scaffolding/README.md @@ -2,7 +2,7 @@ **Not part of the bridge. Never deployed.** `deploy.ps1` only copies `overlay/`, so nothing here reaches a server unless you put it there by hand. -These two scripts produced the measured budget in `docs/PLAN.md` §1. They are kept because those numbers should be reproducible, and because re-running the probe is the only honest way to check whether a change to the plugin's read path got more expensive. +These two scripts produced the measured budget in [PLAN.md](https://gitea.whitlocktech.com/RunicGateway/docs/src/branch/main/link/PLAN.md) §1. They are kept because those numbers should be reproducible, and because re-running the probe is the only honest way to check whether a change to the plugin's read path got more expensive. | File | Server path when testing | What | |------|--------------------------|------|