Skip to content

Command layer

rebaserHEAD edited this page Oct 18, 2026 · 4 revisions

explanation, committed verified 2026-10-18 bootstrap efc697d run 2026-10-18

How the command layer works as built: one dispatcher behind every front end, the checks it runs, what it audits, and the first commands. The local console is the only front end so far; the web console, the player portal and in-game commands are on Command layer design.

The shape

An admin action is a command: a definition naming its parameters, its permission, whether it's console-only, and what it runs. A front end hands the dispatcher one line of text and the actor who typed it, and gets one reply back.

flowchart TD
    CON["Local console"] -->|"a line, as the console actor"| D["Dispatcher"]
    D -->|"checks, then runs"| CMD["Command"]
    CMD -->|"posts, waits for the reply"| AO["Account owner"]
    D -->|"one audit row"| WB["Write-behind queue"]
Loading

The dispatcher runs its checks in this order, and stops at the first that fails:

  1. The line splits into words, double quotes holding a phrase together. An empty line, or one with an open quote, is refused.
  2. help lists the commands the actor may run, with their usage.
  3. The command is found by its two-word name, then its one-word name.
  4. The actor has to hold the command's permission.
  5. A console-only command is refused from in game.
  6. A line with control characters or broken text is refused.
  7. The number of arguments has to fit; the reply shows the usage when it doesn't.
  8. Each argument passes its parameter's own check.
  9. The command runs. One that throws is logged and answered as failed.

A command ends one of four ways: done, refused (understood and declined), denied (for want of a permission, or console-only), or failed. The permission check comes before the argument checks, so an actor without the permission learns only that it's denied.

The audit

Every command that resolves leaves one audit row, denials included: the time, the actor, the front end, the action, its target, the other arguments, the address and the outcome. Rows go through the write-behind queue into the ops schema, one after another in order, and each value is cut to its column's width so a row can't fail to save. An empty line, a line that doesn't parse, an unknown command and help leave none.

A secret stays out of the audit, the reply and the log. A value is recorded only when its parameter isn't secret and the value passes that parameter's check, so a password typed into the email slot isn't recorded either. A usage line shows parameter names, never values.

The first commands

Command layer commands lists every command: its usage, the permission it needs, whether it's console-only and what it does. It's generated from the server's command list, BuiltinCommands, which the server registers its commands from too, so the page can't drift from what the server runs. help at the console lists the ones the actor typing it may run. help, a refused argument count and the page all show the same usage line.

The arguments have fixed limits: an email is at most 254 characters and has to look like an address, a password is 1 to 128 characters, and a suspension's reason is at most 200. account suspend takes a number of hours or forever, and kicks the account's session if it's online. account create stores a random salt and an SRP6 verifier from the email in lower case. Each command's answer waits for the owner, and for its commit where it writes.

Front ends

The local console reads each line from the server's standard input and dispatches it as the actor console, which holds every permission. It runs when Cli:Enabled is on, the default, and input isn't redirected. Host has where it starts.

In game and the web are front ends the dispatcher already knows by name, with no code behind them yet.

Knobs

Setting Default Sets
Cli:Enabled on Whether the server reads commands from its console

The field limits above are fixed in code.

Known edges

  • Console-only commands are refused only from in game; decide how the web front end is treated before it's built.
  • help lists console-only commands to an in-game actor who holds their permission.
  • Roles and in-game GM commands arrive after the first stage, so the console actor's every-permission is the only grant.

Where the code lives

Piece Path
The dispatcher, definitions, actors and the line splitter Source/NexusTomorrow.Commands/
The account and server commands, and the list the server registers (BuiltinCommands.cs) Source/NexusTomorrow.Commands/Builtin/
The console front end Source/NexusTomorrow.Server/ConsoleFrontEnd.cs
The audit row Source/NexusTomorrow.Persistence/Ops/
Tests Tests/NexusTomorrow.Commands.Tests/

Clone this wiki locally