docs(rust): stage 5 built — Dangerous Treasures (PROTOCOL §20.8, PLAN_REDESIGNS §14.3.18)

- rust-link/PROTOCOL.md §20.8: hello's integrations.dangerousTreasures; the
  dt.started / dt.won / dt.ended events and their fields; dt.start, dt.opened
  and the dt.error reasons (dt-not-ready, dt-no-spot, refused among them); the
  tally's treasuresWon; map.live's treasure rows and their seed; the sidecar's
  POST /dt/start; and the website side (classes, per-viewer reading, triggers,
  the step, Treasure Hunter). §17.3's world row gains `treasure`.
- modules/rust/PLAN_REDESIGNS.md §14.3.18: the stage-5 record. Three things
  §14.3.4 had wrong or unsaid (the key's join is exact; "started" is the hook,
  never DT's text, with a fourth outcome `refused`; the Carbon walk row now
  expects the step to work), ten points settled in code, the tests, the rig
  compile and the walk rows. Pointers from §9's summary and §14.3.4.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
2026-10-15 06:45:33 -05:00
parent 8829222f18
commit fa696e9c84
2 changed files with 176 additions and 2 deletions

View File

@@ -930,7 +930,7 @@ pulls) is research, not a walk, so it still comes first:
answered before code: **written on 2026-10-14 as §14.3**, from D361–D369, and answered as D370–D376. Then the
build, in §14.3.11's nine stages (two of them core), §13 first. **Stage 1, §13, was built on 2026-10-15
(§14.3.14)**, with D378 and D379. **Stage 2, core's `retryAfterMs` (MODULE_API 1.15.0), was built on
2026-10-15 (§14.3.15).** **Stage 3, TruePVE in the zone step, was built on 2026-10-15 (§14.3.16)**, and **stage 4, Dynamic PVP, the same day (§14.3.17).**
2026-10-15 (§14.3.15).** **Stage 3, TruePVE in the zone step, was built on 2026-10-15 (§14.3.16)**, and **stage 4, Dynamic PVP, the same day (§14.3.17)**, and **stage 5, Dangerous Treasures, the same day (§14.3.18).**
**Then one walk, on Oxide and Carbon, of everything still owed (D331):** §2.7; §11's rows; §12.9; §13's and
§14's rows; the in-game rows
@@ -2588,6 +2588,9 @@ the column and category.
see *"not ready yet"*, the automatic retry and the manual retry; win one and see the line, the column and the title.
On Carbon: the step refused with Rust-Plugins#34 (until D363 clears).
> **Built on 2026-10-15** (§14.3.18), specified in PROTOCOL.md §20.8. The key's join, how a start that opened
> nothing is recognised, and the Carbon row differ from this text; §14.3.18 says how.
#### 14.3.5 Guarded Crate, with NpcSpawn (D361, D364)
**Hello.** `integrations.guardedCrate`: `{ loaded, version, npcSpawn: { loaded, version }, events: […] }`.
@@ -3032,6 +3035,69 @@ are exercised by §14.3.3's walk rows.
**Walk rows** are §14.3.3's, at the end walk, with one more: hotload the bridge while a zone stands and see
the ring still drawn (the seed).
#### 14.3.18 Stage 5, built: Dangerous Treasures (2026-10-15)
Built in Rust-Plugins, Rust-Link and Module-Rust, specified in [PROTOCOL.md](../../rust-link/PROTOCOL.md) §20.8
and §17.3. `PROTOCOL_VERSION` stays 14. Builds: Rust 25902425, Oxide 2.0.7830, Carbon 2.0.262 (the latest of
each that day); the code read is Dangerous Treasures 3.0.0, the version the §14.2 test ran and still the newest
on uMod. **Module-Rust moves to MODULE_API 1.15.0** (`coreApi ^1.15.0`, `ci/core-ref.json` pinned to website
`main` at #215's merge), because the step answers DT's warm-up with `retryAfterMs` (§14.3.15).
**Three things in §14.3.4 were wrong or unsaid, found in DT's source:**
1. **The key's join is exact, not "the first start within ten seconds".** DT raises `OnDangerousEventStarted`
inside the call that opens the chest (the chest's radius setter runs its `Awaken`), so a start our `dtevent`
caused is heard before `ConsoleSystem.Run` returns. The bridge holds the key for the length of that call and
no longer; a natural start ten seconds later can never take it.
2. **"Started" is the hook, never DT's text.** §14.3.4 told the outcomes apart by the reply *"Unable to obtain a
valid position"*, but DT words every reply from its lang file, which an operator may translate. The bridge
reads DT's own *Manual Event Failed* message through the lang API and compares the reply with that; any
other reply with nothing opened is **`refused`**, a fourth outcome the plan did not have (a difficulty DT's
config no longer has, or its console command renamed), which is not retried.
3. **The Carbon walk row is out of date.** §14.3.4 expected the step refused on Carbon (Rust-Plugins#34). Stage 1
found the console probe true on Carbon from the bridge's own path (§14.3.14 item 7), and `rg.world` read
`consolePlugins=True` on the Carbon rig again today. So on Carbon the step is expected to **work**, and the end
walk checks that instead; it is still refused wherever the probe reads false.
**Settled in the code, and overrulable:**
1. **DT's warm-up window starts when the bridge first saw DT loaded**: DT's own load, or the bridge's when DT was
already there. It can only start late, so a bridge hotloaded beside a long-running DT reads a no-spot as
*not ready* for up to fifteen minutes (a ten-minute retry instead of a one-minute one), never the other way.
2. **A win is placed at the running chest nearest the winner** (within 100 m), since the hook does not say which
chest; else at the winner. `invaders` names at most 32 and `invaderCount` counts them all.
3. **Running chests are found at load by their component.** DT has no API that lists them, so the seed looks for
large wooden boxes carrying DT's `TreasureChest` component, at the world's ready and at DT's load.
4. **The winner's name is the presence audience's, the invaders and every Steam id staff's.** How many fought is
a count and is public. A start's `key` is staff's.
5. **A level is 0, 1 or 2**, as DT ships them; blank is Easy. An operator's own extra levels are not offered.
6. **The Treasures column shows where the server reports DT, or the page's rows count a treasure**, so a wipe
won before DT was removed still shows what was won.
7. **`refused`, `dt-missing`, `console-unavailable`, `bad-level` and `malformed` are permanent failures**; only
`dt-no-spot` and a game that is down retry on core's ordinary delay, and `dt-not-ready` in ten minutes.
8. **A server that has not said whether it has DT is left to the plugin**, as a zone's TruePVE is (§14.3.16).
9. **Triggers' cooldown subject is the server**, so a busy hour of treasures is one notice per cooldown; a start
carries `byEvent` when one of the site's steps made it.
10. **The admin integrations read gains `console`**, so the server settings' plugin line can say DT is loaded but
cannot be started there.
**Tests.** Bridge: `checkPlugin.js` (81 hooks, every one void and listed), 18 tests. Compiled and loaded on both
rigs; `rg.world` read `dangerousTreasures=False treasures=0` on each, and both were put back on the protocol-13
bridge. DT itself is not on the rigs; its hooks and the start are exercised by §14.3.4's walk rows. Sidecar: 72
tests (one new, the stamp), `fmt` and `clippy` clean. Module-Rust server: `test/dangerousTreasures.test.js`, 16
new (the public read the grid, never the position or the key; the winner's name for the presence audience, the
Steam ids and invaders for staff; the feed reads a stored win per viewer; the report read leniently; the step's
price, levels, dry-run refusals for DT absent and the console unavailable, and a server that has not said left
to the plugin; the key and level on the wire; not ready with the ten-minute retry; no spot, a refusal and a
game down; a repeat; the tally's count, the column's sort; the triggers and their variables; an old treasure
tells nobody), and the catalogue, title and registration tests extended: 627/627 and every check. Client: three
new in `feed.test.js`, 92/92, the build and externals. Booted against the newly pinned core: 45 triggers, 13
actions, 11 budgets, 21 option sources; the 89 routes unchanged.
**Walk rows** are §14.3.4's, at the end walk, with the Carbon row now expecting the step to work, and two more:
hotload the bridge while a chest stands and see it still on the map (the seed); and start one from a run and
read its `dt.started` row's `key` from the staff events API (the web client has no staff feed view).
### 14.4 Questions for the org lead
**Answered on 2026-10-14:** Q17 as proposed, out (D358). **Q18 against the proposal: the end walk waits for