feat(bridge): console commands as event steps — command.run (PLAN_REDESIGNS §16, D382-D385) #41

Merged
whitlocktech merged 2 commits from feat/command-steps into edge 2026-10-16 02:47:41 -05:00
Member

What

The bridge half of PLAN_REDESIGNS §16: a command.run frame (protocol 14, PROTOCOL.md §20.11) that runs console commands a step's author typed.

  • Once, for Run console commands. The step's teardown is stored with the key, not run (D385).
  • Once per online recipient, for Reward by console command. The bridge fills {steamid}, and {name} as one argument quoted the way the game's own BuildCommand quotes one. Offline recipients are skipped and named (D383).
  • { key, teardownOf } runs the teardown kept under another key, at most once, and only where something may have run. This covers a step that failed part-way or whose answer was lost: core reverts those with only the key (D385).
  • At most once per key. The key is written to data/RunicGateway/commands-run.json before anything runs (kept 7 days, at most 500 keys). A repeat answers from the record; a repeat while the run is still going joins it; a run a reload cut off answers interrupted.
  • Spread over frames: whole recipients per frame, up to 30 commands or 8 ms.
  • unknown-command: ConsoleSystem.Run returns null both for an unknown command and for one that replies nothing. So each command runs while the bridge listens to Unity's log for the game's own Command '…' not found line, which is logged synchronously inside the call.
  • No allowlist (D384). EventsEnabled gates it like every world verb. rg.world shows commandKeys and commandsRunning.

Tested

  • Spike on both rigs (Rust 25902425, Oxide 2.0.7830, Carbon 2.0.262): Run's return for unknown, silent and plugin commands; QuoteSafe quoting; ; does not split a command.
  • Compiled on both rigs, then driven through a throwaway plugin that calls the handler with no sidecar, all passing on both frameworks:
    • a repeated key runs nothing;
    • a misspelled second command stops after the first;
    • offline recipients are skipped with their names intact;
    • malformed requests are refused;
    • D385's teardown runs once after a partial run, and not at all when nothing ran or the key is unknown.
  • Rigs restored to the protocol-13 bridge.
  • node scripts/checkPlugin.js and its tests pass.

Walk rows (§16.9) join the end walk (D331).

Pairs with Rust-Link (POST /commands/run), Module-Rust (the two steps) and docs (PROTOCOL §20.11, PLAN_REDESIGNS §16.10).

  • AI-assisted: written with Claude Code (Claude Opus 5.5)

🤖 Generated with Claude Code

https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY

## What The bridge half of PLAN_REDESIGNS §16: a `command.run` frame (protocol 14, PROTOCOL.md §20.11) that runs console commands a step's author typed. - **Once**, for *Run console commands*. The step's `teardown` is **stored with the key, not run** (D385). - **Once per online recipient**, for *Reward by console command*. The bridge fills `{steamid}`, and `{name}` as one argument quoted the way the game's own `BuildCommand` quotes one. Offline recipients are skipped and named (D383). - **`{ key, teardownOf }`** runs the teardown kept under another key, at most once, and only where something may have run. This covers a step that failed part-way or whose answer was lost: core reverts those with only the key (D385). - **At most once per key.** The key is written to `data/RunicGateway/commands-run.json` before anything runs (kept 7 days, at most 500 keys). A repeat answers from the record; a repeat while the run is still going joins it; a run a reload cut off answers `interrupted`. - **Spread over frames:** whole recipients per frame, up to 30 commands or 8 ms. - **`unknown-command`:** `ConsoleSystem.Run` returns null both for an unknown command and for one that replies nothing. So each command runs while the bridge listens to Unity's log for the game's own `Command '…' not found` line, which is logged synchronously inside the call. - No allowlist (D384). `EventsEnabled` gates it like every world verb. `rg.world` shows `commandKeys` and `commandsRunning`. ## Tested - **Spike on both rigs** (Rust 25902425, Oxide 2.0.7830, Carbon 2.0.262): `Run`'s return for unknown, silent and plugin commands; `QuoteSafe` quoting; `;` does not split a command. - **Compiled on both rigs**, then driven through a throwaway plugin that calls the handler with no sidecar, all passing on both frameworks: - a repeated key runs nothing; - a misspelled second command stops after the first; - offline recipients are skipped with their names intact; - malformed requests are refused; - D385's teardown runs once after a partial run, and not at all when nothing ran or the key is unknown. - Rigs restored to the protocol-13 bridge. - `node scripts/checkPlugin.js` and its tests pass. Walk rows (§16.9) join the end walk (D331). Pairs with Rust-Link (`POST /commands/run`), Module-Rust (the two steps) and docs (PROTOCOL §20.11, PLAN_REDESIGNS §16.10). - [x] AI-assisted: written with Claude Code (Claude Opus 5.5) 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
wtclaude added 2 commits 2026-10-16 02:44:17 -05:00
A `command.run` frame (protocol 14, PROTOCOL.md §20.11) runs the console
commands a step's author typed: once, or once per online recipient with
{steamid} and {name} filled in (the name quoted the way the game's own
BuildCommand quotes an argument). D382-D384: no allowlist; offline
recipients are skipped and named.

- At most once per key: the key is written to commands-run.json before
  anything runs; a repeat answers from the record, a repeat while running
  joins the running job, a record a reload interrupted answers
  `interrupted`. Kept 7 days, at most 500 records.
- Spread over frames: whole recipients per frame, up to 30 commands or 8 ms.
- unknown-command: ConsoleSystem.Run returns null both for an unknown command
  and for one that replies nothing, so the run listens to Unity's log for the
  game's own "Command '...' not found" line while each command runs (spiked
  on Oxide 2.0.7830 and Carbon 2.0.262, Rust 25902425). The same capture is
  the reply when Run returns nothing.
- rg.world shows commandKeys and commandsRunning.

Compiled on both rigs and driven through a throwaway plugin (repeat key,
unknown command, offline recipients, malformed requests); rigs restored to
the protocol-13 bridge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
feat(bridge): keep a step's teardown with its key — teardownOf (D385)
All checks were successful
PR Checks / plugin-checks (pull_request) Successful in 9s
5104e0dbcd
Core records nothing for a step that failed or whose answer was lost, and
then reverts it with only the key: no server, no teardown. So a run request
now carries its `teardown`, stored in the key's record and never run with
it, and `{ key, teardownOf }` runs the teardown stored under `teardownOf`,
under its own key, at most once:

- only when something there may have run (some commands ran, or a reload
  cut the run off); otherwise answered with nothing run and nothing kept;
- `busy` while the run it is for is still going;
- a reward carries no teardown (refused `malformed`), and a teardown takes
  no placeholders.

Re-compiled and driven on both rigs (a failed run's teardown ran once, a
repeat ran nothing, nothing-ran and unknown keys ran nothing); rigs
restored to the protocol-13 bridge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
whitlocktech merged commit 594acb5351 into edge 2026-10-16 02:47:41 -05:00
whitlocktech deleted branch feat/command-steps 2026-10-16 02:47:42 -05:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: RunicGateway/Rust-Plugins#41
No description provided.