Skip to content

Command layer

rebaserHEAD edited this page Oct 18, 2026 · 4 revisions

explanation, committed verified 2026-10-18 main 3bdebd6 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

Note

This list is kept by hand until the commands get a generated reference page. help at the console is the live list.

Command Permission Console only Does
account create <email> <password> account.create No Creates an account that can log in: a random salt and an SRP6 verifier from the email in lower case. A password is 1 to 128 characters
account suspend <email> <hours or forever> [reason] account.suspend Yes Suspends an account, kicking its session if it's online. A reason is at most 200 characters
account unsuspend <email> account.unsuspend Yes Lifts the account's suspensions
server status server.status No The accounts online, each owner's queue, the write-behind backlog, and whether the database is reachable
help none No The commands the actor may run

An email is at most 254 characters and has to look like an address. 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 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