fix(examples): a Kits reload owed for the example kits survives an interrupted load (D329) #17

Merged
whitlocktech merged 1 commits from fix/kits-reload-owed into edge 2026-10-09 07:09:40 +00:00
Member

What & why

RunicNPC stage 9e, step 2 (docs/runicnpc/PLAN.md). In the 9d player session on Carbon, the automatic Kits reload after the first load did not take effect, and s6bossc stayed refused ("no kit 'rnpc_juggernaut'") until Kits was reloaded by hand.

Cause, read from the rig's own Carbon log for 2026-10-09 04:49:

  1. The first load wrote the kits and asked for c.reload Kits on a one-second timer.
  2. RunicNPC was loaded again 1 s later. A plugin's timers die when it unloads, so that reload never ran.
  3. examplesWritten was already set, so nothing asked for the reload again.

It is not a first-boot problem. A fresh Carbon boot, a c.load and the file landing on a running server all reloaded Kits correctly. Oxide never shows it: loading RunicNPC makes Oxide recompile and reload Kits itself (// Requires: Kits). Carbon does not do that.

The fix (D329, approved by the org lead):

  • The kits written are now owed a reload, recorded in data/RunicNPC/state.json as kitsReloadOwed and kitsReloadTries.
  • SettleKitsReload runs on every load and when Kits comes back.
  • Once Kits knows every owed kit, the debt is cleared.
  • Otherwise it asks for the reload again, at most 3 times. After that it warns with the command to run (c.reload Kits / oxide.reload Kits) and stops, so a kit Kits never takes cannot cause a reload loop.

The API, hooks and data shape are unchanged apart from two new state fields. A state.json from before this change reads them as empty.

How it was tested

Rust 25797215, Oxide 2.0.7815, Carbon 2.0.262 (all latest). Each case was run on both rigs and each rig was restored afterwards:

Case Carbon Oxide
A first install landing on a running server (Kits has never seen the examples) refused at first load → 1 Kits reload → refused: -, debt cleared same: 2 refused, then 5 profiles, debt cleared
The interrupted state (kits in Kits' file but not in its memory, reload owed, no first load) a later load asked for the reload → refused: - (the session's case, now self-healing) Oxide's own Requires reload already loaded them, so the debt cleared with no extra reload
A debt for a kit that never exists 3 reloads, the warning, stops 3 reloads, the warning, stops
  • node scripts/checkPlugin.js passes, and checkPlugin.test.js passes 24/24.
  • The harness gains s6.examples.reloadSettled (version 0.7.3). It compiled on the Carbon rig. The full s6 group was not run, because the walk site is pushing profiles to the rigs.

Docs: RunicGateway/docs PR for 9e step 2 (D329).

Checklist

  • I have read CONTRIBUTING.md.
  • The change builds and existing tests/checks pass locally.
  • I have added or updated tests/docs where it makes sense.
  • My commits are reasonably scoped with clear messages.

AI-assisted contributions (required)

  • No AI tools were used to produce this contribution.
  • AI tools were used. Tool(s): Claude Code (Claude Opus 5.5). I have reviewed and understand
    every change, and take responsibility for it. AI-authored commits are
    marked with a Co-Authored-By / Assisted-By trailer.

License

  • I agree that my contribution is licensed under this project's license
    (GNU GPL v3.0 or later), and I have the right to contribute it.

🤖 Generated with Claude Code

https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY

## What & why RunicNPC stage 9e, step 2 (docs/runicnpc/PLAN.md). In the 9d player session on Carbon, the automatic Kits reload after the first load did not take effect, and `s6bossc` stayed refused ("no kit 'rnpc_juggernaut'") until Kits was reloaded by hand. **Cause, read from the rig's own Carbon log for 2026-10-09 04:49:** 1. The first load wrote the kits and asked for `c.reload Kits` on a one-second timer. 2. RunicNPC was loaded again 1 s later. A plugin's timers die when it unloads, so that reload never ran. 3. `examplesWritten` was already set, so nothing asked for the reload again. **It is not a first-boot problem.** A fresh Carbon boot, a `c.load` and the file landing on a running server all reloaded Kits correctly. **Oxide never shows it:** loading RunicNPC makes Oxide recompile and reload Kits itself (`// Requires: Kits`). Carbon does not do that. **The fix (D329, approved by the org lead):** - The kits written are now *owed* a reload, recorded in `data/RunicNPC/state.json` as `kitsReloadOwed` and `kitsReloadTries`. - `SettleKitsReload` runs on every load and when Kits comes back. - Once Kits knows every owed kit, the debt is cleared. - Otherwise it asks for the reload again, at most 3 times. After that it warns with the command to run (`c.reload Kits` / `oxide.reload Kits`) and stops, so a kit Kits never takes cannot cause a reload loop. The API, hooks and data shape are unchanged apart from two new state fields. A `state.json` from before this change reads them as empty. ## How it was tested Rust 25797215, Oxide 2.0.7815, Carbon 2.0.262 (all latest). Each case was run on both rigs and each rig was restored afterwards: | Case | Carbon | Oxide | |---|---|---| | A first install landing on a running server (Kits has never seen the examples) | refused at first load → 1 Kits reload → `refused: -`, debt cleared | same: 2 refused, then 5 profiles, debt cleared | | The interrupted state (kits in Kits' file but not in its memory, reload owed, no first load) | a later load asked for the reload → `refused: -` (**the session's case, now self-healing**) | Oxide's own `Requires` reload already loaded them, so the debt cleared with no extra reload | | A debt for a kit that never exists | 3 reloads, the warning, stops | 3 reloads, the warning, stops | - `node scripts/checkPlugin.js` passes, and `checkPlugin.test.js` passes 24/24. - The harness gains `s6.examples.reloadSettled` (version 0.7.3). It compiled on the Carbon rig. The full `s6` group was not run, because the walk site is pushing profiles to the rigs. Docs: RunicGateway/docs PR for 9e step 2 (D329). ## Checklist - [x] I have read [CONTRIBUTING.md](CONTRIBUTING.md). - [x] The change builds and existing tests/checks pass locally. - [x] I have added or updated tests/docs where it makes sense. - [x] My commits are reasonably scoped with clear messages. ## AI-assisted contributions (required) - [ ] No AI tools were used to produce this contribution. - [x] AI tools were used. Tool(s): `Claude Code (Claude Opus 5.5)`. I have reviewed and understand every change, and take responsibility for it. AI-authored commits are marked with a `Co-Authored-By` / `Assisted-By` trailer. ## License - [x] I agree that my contribution is licensed under this project's license (**GNU GPL v3.0 or later**), and I have the right to contribute it. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
wtclaude added 1 commit 2026-10-09 07:07:43 +00:00
fix(examples): a Kits reload owed for the example kits survives an interrupted load (D329)
All checks were successful
PR Checks / plugin-checks (pull_request) Successful in -1m52s
f9210e3a4f
The first load writes the example kits into Kits' file and asked for a Kits
reload on a one-second timer. A timer dies with its plugin, so a second load of
RunicNPC inside that second (the 9d session's, on Carbon) lost the reload, and
examplesWritten was already set: the examples stayed refused ("no kit
rnpc_juggernaut") until Kits was reloaded by hand.

The kits written are now owed a reload in data/RunicNPC/state.json
(kitsReloadOwed). SettleKitsReload, on every load and when Kits comes back,
clears the debt once Kits knows every kit owed, and otherwise asks for the
reload again, at most three times, then warns with the command to run.

Oxide never showed it: loading RunicNPC recompiles and reloads Kits there
(// Requires: Kits). Carbon does not.

Walked on both rigs (Rust 25797215, Oxide 2.0.7815, Carbon 2.0.262): a first
install landing on a running server, the interrupted state, and a debt for a
kit that never exists (three reloads, the warning, no loop). The harness gains
s6.examples.reloadSettled (0.7.3; compiled on the Carbon rig).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
whitlocktech merged commit 667c77e32c into edge 2026-10-09 07:09:39 +00:00
whitlocktech deleted branch fix/kits-reload-owed 2026-10-09 07:09:40 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: RunicGateway/runicnpc-rust#17
No description provided.