Files
docs/modules/rust/PLAN_LAST_FIXES.md
wtclaude 75936d2448 docs(rust): the last fixes before the cutover
The end walk's in-game pass ran on 2026-10-21. PLAN_LAST_FIXES.md records
what it passed and what it found, and puts every fix still open in one
list in building order: W1-W20 and N1 from the passes without a player,
plus the in-game pass's W21 (a reward's message is never pushed to the
game), W22 and W23 (walk and protocol docs that expect the wrong thing)
and N2 (reloading RaidableBases breaks it). It also asks Q37-Q40, lists
the rows still owed with a second player, and the clean-up after the
walk. PLAN_REDESIGNS and the README point to it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-10-21 06:09:14 -05:00

167 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# `module-rust` — the last fixes before the cutover
**Status:** plan, written 2026-10-21 after the end walk's in-game pass. Nothing in it is built yet. Each fix waits
for the org lead's go, and the questions in §5 are answered before the code they shape. It continues
[`PLAN_REDESIGNS.md`](PLAN_REDESIGNS.md) §9.1, which lists W1–W20 and N1 from the passes without a player. This
document adds what the in-game pass found and puts everything in one list, in the order it should be built.
**After this list:** the protocol 14 release, then the cutover of the four Rust repos from `edge` to `main`
([`PLAN.md`](PLAN.md) §34). The release does not need §6's rows with a second player unless the org lead decides
otherwise (Q38).
---
## 1. The in-game pass, 2026-10-21
| | |
|---|---|
| Builds | Rust 25902425, Oxide 2.0.7830, Carbon 2.0.262 (each the latest that morning) |
| Site | website `edge` (MODULE_API 1.17.0, Steam sign-in) with Module-Rust `edge`, on the walk database, at `127.0.0.1:3270` |
| Bridge | Rust-Plugins `edge` on both rigs, protocol 14 sidecars |
| Player | A, the org lead's own Steam account, linked through Steam sign-in |
| Phone | the Android emulator on the walk machine, app from `Android-app` `edge` |
The rows are in [`PLAYER_WALK.md`](../../rust-link/PLAYER_WALK.md), "The end walk's in-game pass".
| Part | Result |
|---|---|
| 1, Steam sign-in on the web | 1.1–1.6 pass. 1.7 needs a second player (§6) |
| 2, in game | 2.1, 2.2, 2.4–2.14 pass. 2.11 passed on Carbon. 2.3 passed for its NPC count; that PvP is off and the lock holds needs a second player (§6). 2.9 and 2.10 passed once W21 was patched on the walk site |
| 4, the phone | 4.2 and 4.3 pass. 4.1 reaches steamcommunity.com; the org lead chose not to finish a Steam sign-in on the emulator, and Part 1 covers the sign-in itself. 4.4 was not run |
| Carbon's share | Only 2.11 was walked. The org lead dropped the rest: the bridge file is the same on both frameworks, and Carbon's halves of every integration passed without a player on 2026-10-19 |
---
## 2. What the in-game pass found
| # | Where | What |
|---|---|---|
| **W21** | Module-Rust | **A reward's message never reaches the game.** `server/permSync.js` pushes `groups`, `grants`, `credits` and `retire`, but not `notices`. The model builds the notices and the hold keeps them, so they are dropped only at the push. No kit reward, lend or give has ever told its player anything. The sidecar passes `notices` through, and the plugin shows them as written. **The second real bug.** |
| W22 | docs | Three rows of PLAYER_WALK's in-game pass expect the wrong thing. **2.8:** items on the extra page go to the inventory only when the first page is full. Backpacks first moves them into free slots on the pages that are left. **2.9:** a reward's message goes to chat **or** a popup, as the step chooses, not both. **Before you start:** it names neither BetterChat on both rigs nor the title rules that 2.1, 2.4, 2.12 and 2.13 read. |
| W23 | docs | **`rbevent setowner A` reads as a purchase, not a lock.** RaidableBases 3.2.2's `TrySetPayLock` takes `paylock = !args.Contains("lockout")`. The plain command raises `OnRaidableBasePurchased`, so the feed shows "bought". Only `rbevent setowner A lockout` raises `OnRaidableBaseLocked`. PROTOCOL.md §20.12, PLAN_REDESIGNS §11.4 and PLAYER_WALK 2.2 say the plain command locks. |
| N2 | docs | **Reloading RaidableBases while it runs breaks it.** After `oxide.reload RaidableBases` (three tries, two of them with bases up), its list of live raids held a null. Every hook that walks the list then threw: damage, SAM sites, player commands and `/buyraid`'s cooldown check, so a purchase did nothing and charged nothing. A full server restart cleared it. Operators should change RaidableBases' config with a restart, never a reload. A third-party bug, but worth a line in OPERATING.md. |
What the pass proved for the first time: the D333 messages on Oxide and Carbon, online and on waking, in chat
and as popups (once W21 was patched); a payment made while the player was offline and told on waking; a
command reward with the player's real id and name; a two-page backpack in the staff view, on the account page
and in the app, with another player's backpack refused; the extra page's items going to the inventory and then
to the ground; the four titles in chat; and on Carbon, a give, a lend and a bigger backpack reaching a real
player who had joined it. (W17 is still true for players who have never joined.)
---
## 3. The whole list
From PLAN_REDESIGNS §9.1 (W1–W20, N1) and §2 above. **Bold** rows are real bugs, and everything else is wording,
lag or docs. "Proposed" is a suggestion for the org lead, not a decision.
### 3.1 Module-Rust
| # | Proposed fix |
|---|---|
| **W21** | Send `notices: held.payload.notices` with the push, plus a test that a sync with an untold notice carries it. Already patched in the walk site's copy of the module for the walk. |
| **W4** | Stamp the helicopter and Bradley credit rule onto each feed row at ingest, and read the stamp when the line is drawn. Rows from before the fix keep today's reading. |
| W3 | Calling the Travelling Vendor while one is out says so ("one is already out") instead of "called 1". |
| W6 | "A locked crate dropped by a Chinook is being hacked." |
| W7, W11 | Before an "is it loaded" refusal, ask the sidecar live rather than reading the 30-second status poll. |
| W8 | A RaidableBases profile write's audit row names RaidableBases, not "@data". |
| W10 | The backpack sizes picker lists each size once, naming every server that offers it. |
| W13 | A profile name on both servers shows each server's difficulty when they differ. |
| W14 | Capital letter after the full stop. |
| W15 | Both of Economics' refusals of a staff deposit answer 409. |
| W16 | `failedNote` names only what happened (`at-limit` alone reads "at the balance limit"). |
| W17 | When the sync report's `notLanded` names a lent or given permission, the run log and the server's sync state say so ("lent to 2; 1 lands when they first join Carbon") instead of "in sync". It does land once they join, because every sync pushes the whole set. |
| W18 | Read the event's own time limit from the server for the placement note, or drop the number. |
### 3.2 The bridge (Rust-Plugins)
| # | Proposed fix |
|---|---|
| W9 | A rolled-back RaidableBases profile write reports RaidableBases' own error, not the tail of the server log. |
| W12 | `raid.ended` carries the base's id, and its run and key when a run made it, as PROTOCOL says. |
### 3.3 Core (website)
| # | Proposed fix |
|---|---|
| W1 | On a reconnect, check expiry before marking a resource orphaned, so the log shows only `resource.expired`. |
| W2 | A phase waiting to advance with its steps done reads "Phase p1: steps done, waiting to advance". |
| W5 | A dry run that passed on a draft counts for the version published from that draft when the spec is unchanged. |
| **W19** | Module-uo and Module-Rust cannot share a site. A design change, so it needs Q37 first. |
### 3.4 Plan against core
| # | Proposed fix |
|---|---|
| W20 | §14.3.4's "manual retry" cannot be done, because core retries only a failed step. Q39 decides whether to change the plan or core. |
### 3.5 Docs
| # | Proposed fix |
|---|---|
| N1 | OPERATING.md: installing RaidableBases' free edition over a paid pack rewrites the pack's profiles and drops their bases. |
| N2 | OPERATING.md: change RaidableBases' config with a server restart, never a reload. |
| W22 | Correct PLAYER_WALK 2.8, 2.9 and "Before you start" as §2 says, and trim "Carbon's share" to 2.11, as walked. |
| W23 | Correct PROTOCOL.md §20.12, PLAN_REDESIGNS §11.4 and PLAYER_WALK 2.2: `rbevent setowner A lockout` locks, and the plain form reads as a purchase. |
---
## 4. Order of building
One PR per repo per stage, each announced, with a pause for the org lead before the next stage.
1. **The two bugs, W21 and W4** (Module-Rust), each with its test, then a walk-site check: one lend with a
message (W21), and a past helicopter line read under a changed credit rule (W4).
2. **Module-Rust's small fixes:** W3, W6, W7/W11, W8, W10, W13–W18.
3. **The bridge:** W9, W12. A protocol change only if W12 adds fields PROTOCOL already lists, so no version bump.
4. **Core:** W1, W2, W5, and W19 once Q37 is answered. W19 may need a MODULE_API minor bump and a new core pin
in Module-Rust and the Integration Kit.
5. **Docs:** N1, N2, W20 (per Q39), W22, W23, and this document's status.
6. **The release and the cutover**, on the org lead's go.
---
## 5. Questions for the org lead
**Q37 — W19, two game modules on one site.** Today `admin.users.detail` takes one provider, so a site with
Module-uo and Module-Rust starts without the second. For example, an admin opens a user who plays both games:
- (a) **Tabs:** the user page shows a *UO* tab and a *Rust* tab, one per module that fills the slot. The slot
takes several providers.
- (b) **Stacked:** each module's panel appears one under the other on the same page.
- (c) **Leave it:** one game module per site, and core refuses the second with a clear message at boot.
**Q38 — the release and the second player.** Part 3 (hand revive, healing, a PvP kill, the map walk, events step
7), 1.7 and 2.3's PvP/lock check need a second player. Do the release and cutover wait for them, or go ahead and
walk them when a second player is free?
**Q39 — W20, the manual retry.** With Dangerous Treasures' fifteen-minute warm-up, core's automatic retry already
succeeds on its third try. Either (a) PLAN_REDESIGNS §14.3.4 drops "the manual retry", or (b) core lets staff
retry a step that is still pending.
**Q40 — what the walk leaves on the rigs.** BetterChat was added to the Oxide rig for the titles, and the walk
site now has title rules for the richest, raids, treasures and guarded crates. Keep both, or remove them with the
rest of §7?
---
## 6. Still owed, with a second player
1.7 (someone else's Steam account refused), 2.3's no-PvP-damage and lock-holds, all of Part 3, and the second-player
rows of 4.4. They are written in PLAYER_WALK and need no change.
---
## 7. Cleaning up after the walk
Done on the org lead's go, after §5's Q40:
- **Oxide rig:** remove A from the owners (`removeowner`, then `server.writecfg`). Remove the walk-only
RgKitProbe plugin, which holds god mode and a teleport command, and the RgWalk stand-in plugin. Restore
RaidableBases' config from the walk's backup, which takes away the 100-coin Easy and Medium buy costs, and
**restart** the server rather than reloading (N2).
- **Walk site:** remove A's test grants (`backpacks.use` on Oxide; the `backpacks.use` given on Carbon), and
the title rules if Q40 says so.
- **Steam:** rotate the Steam Web API key, which was pasted into the chat that ran the walk, and put the new
one in Admin → Auth → Steam.
- **W21** stays patched only on the walk site until §4 step 1 lands. Nothing else depends on the walk site's copy.