Skip to content

Command layer dispatcher

rebaserHEAD edited this page Oct 18, 2026 · 1 revision

reference, committed verified 2026-10-18 bootstrap c3409ba run 2026-10-18

The dispatcher: the checks it runs on every command line, the four ways a command ends, the audit it writes, and the limits on the first commands' arguments. Every command is listed on the generated Command layer commands, and how the layer fits the server is on Command layer.

The checks

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.

The permission check comes before the argument checks, so an actor without the permission learns only that it's denied. help, a refused argument count and the commands page all show the same usage line.

Outcomes

Outcome Means
Done The command ran
Refused Understood and declined, by the command or its owner
Denied For want of a permission, or console-only
Failed The command threw

The audit

Every command that resolves leaves one 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' arguments

Argument Limit
An email At most 254 characters, and it has to look like an address
A password 1 to 128 characters; quote one that has spaces
A suspension's length A number of hours, or forever
A suspension's reason At most 200 characters

account create stores a random salt and an SRP6 verifier from the email in lower case, and account suspend kicks the account's session if it's online. Each command's answer waits for the owner, and for its commit where it writes.

Front ends

Front end Holds
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
In game, the web Known to the dispatcher by name, with no code behind them yet

Known edges

  • Console-only commands are refused only from in game; how the web front end is treated is decided before it's built.
  • help lists console-only commands to an in-game actor who holds their permission.
  • The argument limits are fixed in code.

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