NEUR_OS // FIELD MANUAL

Build the breach.
Know the machine.

Everything you need to operate a cyberdeck, write NeurOScript, and get back out before the trace lands.

SYSTEM ONLINE
manuals
02
interface
NeurOShell
runtime
Lua 5.4
01 / deck interface

NeurOShell Reference

NeurOShell is the command-line interface on a powered cyberdeck. It is used to inspect the deck, create and manage scripts, read namespace manuals, and run NeurOScript programs. NeurOShell commands act on the deck itself; NeurOScript is the Lua-based language executed by the deck.

For the scripting language and namespace APIs, see the NeurOScript Reference.

#Opening the Shell

The shell is available while a powered cyberdeck is in your inventory and held in both hands. Cyberdecks are two-handed items, so holding one normally fills both hand slots.

hold Ghost Deck
power Ghost Deck on
> status

The order of hold and power does not matter. If the deck is stashed, dropped, powered off, or no longer occupies both hands, its shell becomes unavailable.

Every shell command begins with >:

> help
> list
> man net
> ./probe 10.100.101.1

Whitespace after > is optional, so >list and > list are equivalent. This reference includes the space for readability. Built-in command names are case-insensitive; script names are matched as written.

#Quick Start

Create, debug, assemble, and run a script:

> write hello

Enter this line in the editor:

system.log("Hello from NeurOS.")

Save and leave the editor, then finish the lifecycle:

:wq
> debug hello
> asm hello
> ./hello

write produces an unassembled script. debug can test that source directly, but normal execution with ./ requires it to be assembled first.

#Command Summary

Command Description
> help [<command>] List shell commands or show help for one command.
> status Show deck hardware, power, heat, and resources.
> list List scripts in memory and storage.
> man [<namespace>] List or read NeurOScript namespace manuals.
> nmcli [<object>] Inspect and control the deck's NetworkManager.
> ps [<pid|script>] Show the running script or inspect it in detail.
> write <script> Create or edit a loaded script.
> cat <script> Print a loaded script's source.
> debug <script> Test a loaded script without changing the deck or network.
> asm <script> Assemble a loaded script for execution.
> ./<script> [args...] Run a loaded, assembled script.
> kill <pid|script> Stop the running script by PID or script name.
> unload <script> Move a script from memory to storage.
> load <script> Move a script from storage to memory.
> rm <script> Permanently delete a script.
> shutdown Power off the deck and close the shell.
> reboot Power-cycle the deck.

#NetworkManager (nmcli)

All interactive networking is managed through nmcli. NeurOS follows the familiar object/command form:

> nmcli [help|status|hostname|networking|radio|connection|device]

With no arguments, nmcli shows overall status. Common aliases are con/c, dev/d, net, host, and r.

#Status and Identity

> nmcli status
> nmcli hostname
> nmcli hostname black-ice

The hostname is the deck's network-visible identity, not the cyberdeck object's name. It is lowercase, 1–32 characters, and may contain letters, digits, and internal hyphens.

#Networking and Radios

> nmcli networking [status|on|off|connectivity [check]]
> nmcli radio [all|wifi|wwan|satellite|mesh|quantum [on|off]]

Disabling networking drops every active connection. Disabling a radio drops connections using adapters of that type. Hostname and switch settings persist across reboot, but active connections do not. Ethernet is not radio-controlled.

#Devices and Discovery

> nmcli device status
> nmcli device show [<interface>]
> nmcli device scan [<interface>]

Devices are local installed adapters such as wlan0, eth0, and mesh0. Scanning lists reachable remote nodes. An active connection can expose nodes behind it, so later scans may reveal a deeper network frontier.

#Connections

> nmcli connection show [--active] [<id>]
> nmcli connection up <network-id> [ifname <interface>]
> nmcli connection down <id>

If ifname is omitted, NeurOS chooses the enabled adapter with the most free bandwidth. Connection IDs may be supplied in full or by a unique prefix of at least four characters. Connections consume bandwidth on their selected adapter and persist until disconnected, networking is disabled, their radio is disabled, or the deck powers off.

nmcli controls transport only. Probing capabilities, breaching ICE, protected reads, remote commands, and payload installation remain NeurOScript operations. Breach authorization is local to one script execution and is never retained by the shell. Network-changing nmcli commands are blocked while a script runs; read-only status, show, connectivity, and scan commands remain available.

#Script States and Locations

> list divides scripts by location and shows the state of each loaded script.

#Locations

Location Resource Meaning
Loaded (Memory) RAM The script can be read, edited, debugged, assembled, or run.
Stored (Disk) Storage The script persists without using RAM, but must be loaded before use.

Loading and unloading are moves, not copies. load removes a script from storage and places it in memory. unload removes it from memory and attempts to place it in storage.

#Loaded States

Marker Meaning
[UNASSEMBLED] Source exists but cannot be run with ./. It can still be edited or debugged.
[READY] Assembled and ready to run.
[ACTIVE] Currently running.

Editing an existing script replaces its source and returns it to [UNASSEMBLED]; assemble it again before the next normal run.

Only one script can run or be debugged at a time. A running script cannot be removed or unloaded; stop it or wait for it to finish.

#Qn and Capacity

NeurOS measures script size and deck capacity in Qn (Quan):

  • Loaded scripts consume RAM according to their loaded size.
  • Stored scripts consume disk according to their compiled size.
  • load fails if the script does not fit in available RAM.
  • write fails to save a new or edited script if its loaded size does not fit
  • in available RAM.

  • unload permanently loses the script if no storage is installed or the
  • script does not fit in available storage.

Use > status for total resource information and > list for current RAM and storage use.

#Command Details

#help

> help
> help <command>

Without an argument, lists every built-in and the ./ execution form. With an argument, shows that topic's usage and description.

Aliases and topic normalization:

  • > ? is an alias for > help.
  • > help ? opens the help topic.
  • > help assemble opens the asm topic.
  • Any topic beginning with ./, such as > help ./probe, opens the script
  • execution topic.

help documents shell commands. Use man for NeurOScript namespaces.

#status

> status

Shows the deck's power state, installed hardware, available capabilities, thermal state, RAM, storage, bandwidth, and other deck resources.

#list

> list

Lists scripts loaded in RAM and scripts stored on disk. Loaded entries show their loaded size and [UNASSEMBLED], [READY], or [ACTIVE] state. Stored entries show their compiled size.

#man

> man
> man <namespace>

Without an argument, prints the manual index available to the deck. With a namespace, opens its manual page:

> man system
> man net
> man interface

The manual pages describe NeurOScript APIs, not shell built-ins. Hardware can control which namespaces a deck can use at runtime. The complete API is also listed in the NeurOScript Reference.

#write

> write <script>

Creates a loaded script or opens an existing loaded script in the line editor. It does not open a stored-only script; load that script first.

Script names:

  • Must begin with a letter.
  • May contain letters, digits, hyphens, and underscores.
  • May be at most 32 characters long.
  • May not contain spaces.

Examples of valid names:

probe
door_unlock
scan-v2

The most useful editor commands are:

Editor command Effect
<text> Append a new line to the buffer.
: Display the buffer with line numbers.
:h Display full editor help.
:w Save without leaving the editor.
:wq Save and leave the editor.
:q Leave, prompting to save if changed.
:q! Leave without saving.
:u Undo.
:uu Redo.
:DD Clear the entire buffer.

Saving requires the same powered deck to remain held in both hands. If the deck becomes unavailable while editing, the buffer is not saved.

#cat

> cat <script>

Prints the source of a loaded script and its loaded size. cat does not read scripts directly from storage; use load first.

#debug

> debug <script>

Tests a loaded script without changing the deck, network, or connected devices. Assembly is not required, and any output or errors are displayed.

The debugger can test every NeurOScript namespace even if the current deck does not have the hardware needed for a normal run.

#asm

> asm <script>
> assemble <script>

Assembles a loaded [UNASSEMBLED] script and marks it [READY]. assemble is an alias for asm.

An edited script must be assembled again.

#Script Execution

> ./<script> [args...]

Runs a loaded, assembled script:

> ./probe
> ./probe 10.100.101.1 fast

Arguments are split on whitespace and exposed to NeurOScript through the one-indexed global arg table:

local target = arg[1]
local mode = arg[2]
system.log("arguments: " .. #arg)

NeurOShell does not interpret options, quotes, pipes, redirection, environment variables, or wildcard expansion. Every token after the script name is passed as a string.

A normal run:

  • Requires the script to be loaded and assembled.
  • Uses only namespaces enabled by installed hardware.
  • Adds heat and records the script as [ACTIVE] while it runs.
  • Takes time based on loaded size and processing speed.
  • Applies successful network and device effects when the run completes.
  • Does not apply unfinished effects if the script fails or is aborted.

If heat reaches the deck's cooling capacity, NeurOS aborts the script, powers the deck off, and disengages the shell. The deck cannot power back on until it has cooled below its lockout threshold.

#ps

> ps
> ps <pid|script>

Without an argument, ps shows the running script's PID, mode, state, elapsed time, RAM use, and command. The detailed form also shows its expected runtime, arguments, and whether it is stopping. Finished scripts are not listed; an idle deck reports No processes.

A script may be starting, running, waiting to finish, or stopping.

#kill

> kill <pid|script>

Stops the running script by PID or exact script name. A script may take a moment to stop. A waiting script stops immediately.

#unload

> unload <script>

Removes a loaded script from RAM and attempts to save it to disk. If a stored script with the same name exists, the unloaded version replaces it.

This command has no confirmation prompt. If the deck has no storage, or if the script does not fit in available storage, the script is permanently lost.

#load

> load <script>

Moves a stored script from disk into RAM. The operation fails without changing the stored copy if there is not enough available RAM. A successfully loaded script retains its assembled or unassembled state.

#rm

> rm <script>

Permanently deletes a script, whether it is loaded in memory or stored on disk. This command has no confirmation prompt and cannot be undone.

#shutdown

> shutdown

Aborts running scripts, powers the deck off, and disengages the shell. Power the deck back on with the regular game command:

power <deck> on

#reboot

> reboot

Aborts running scripts and power-cycles the deck. The shell remains available if the deck successfully returns to the powered-on state. An overheated deck can remain off until it cools sufficiently.

#Common Workflows

#Create and Run

> write netscan
:wq
> debug netscan
> asm netscan
> ./netscan

#Edit an Existing Script

> write netscan
:wq
> debug netscan
> asm netscan

Saving the edit makes the script unassembled, so the final asm is required.

#Archive and Restore

> unload netscan
> list
> load netscan

Check available disk space before unloading: a failed storage fit loses the script.

#Run with Arguments

> ./quickjack door_lock quiet
local node_type = arg[1]
local mode = arg[2]

#Shell Limits and Safety Notes

  • The shell operates only on the powered deck currently held in both hands.
  • Commands take one script name; script names cannot contain spaces.
  • There are no pipelines, command chaining, background operators, or file
  • paths.

  • rm and a storage-less or storage-full unload are destructive and do not
  • ask for confirmation.

  • shutdown, reboot, overheating, and kill abort running scripts.
  • Script limits are documented in the
  • NeurOScript Reference.

02 / language & APIs

NeurOScript Reference

NeurOScript (NOS) is the scripting language used by the NeurOS operating system on cyberdecks. It uses Lua syntax and provides commands for network intrusion, device manipulation, and deck automation.

For the cyberdeck command line used to create, assemble, manage, and run these scripts, see the NeurOShell Reference.

#Language Basics

NOS uses Lua syntax. Variables are declared with local, strings use single or double quotes, tables (arrays/dicts) use curly braces, and .. concatenates strings.

local name = "Ghost"
local count = 42
local devices = {}
local msg = "Deck: " .. name

#Control Flow

if condition then
    -- ...
elseif other then
    -- ...
else
    -- ...
end

for i = 1, 10 do
    -- ...
end

while condition do
    -- ...
end

#Tables

Tables are the only data structure. They work as both arrays and dictionaries.

-- Array style
local list = {"alpha", "bravo", "charlie"}
for i = 1, #list do
    system.log(list[i])
end

-- Dict style
local info = {name = "Panel", level = 3}
system.log(info["name"])

#Script Arguments

Arguments supplied when a script is run from NeurOShell are available through the global arg table. Run a loaded, assembled script with arguments after its name:

> ./probe 10.100.101.1 fast

NeurOScript receives those arguments as one-indexed strings:

local target = arg[1]  -- "10.100.101.1"
local mode = arg[2]    -- "fast"
local count = #arg     -- 2

system.log("Target: " .. target)

The arg table is always available. If the script is run without arguments, #arg is 0 and arg[1] is nil:

if #arg == 0 then
    system.log("Usage: ./probe <target> [mode]")
    return
end

NeurOShell splits arguments on whitespace. It does not process quotes, escapes, variables, wildcards, or other shell expansion, so a single argument cannot contain spaces. All arguments arrive as strings; use tonumber(arg[n]) when a script requires a number.

See Script Execution (./) in the NeurOShell reference for the command-side details.

#Available Standard Library

The following Lua standard library functions are available in NOS:

  • math: sin, cos, tan, sqrt, exp, log, pow, random, randomseed, floor, ceil, abs, min, max, modf, fmod, huge, pi
  • string: format, rep, gmatch, gsub, match, find, sub, upper, lower, reverse, len, byte, char
  • table: insert, remove, concat, sort, pack, unpack
  • globals: print, tostring, tonumber, type, ipairs, pairs, next, pcall, xpcall, error, assert, unpack, select, rawequal, rawlen

Functions not listed above are not available in NeurOScript.

#Namespaces

Namespaces are groups of functions that NeurOS exposes to scripts. Some are always available; others require specific hardware to be installed in the deck.

#Always Available

#system

Deck basics: logging, introspection, control.

Function Qn Returns Description
system.log(message) 0.1 string Display a message on the deck console. Returns the formatted log entry.
system.info() 0.1 table Returns {os, deck, owner} — the OS version, deck name, and owner name.
system.uptime() 0.1 number Seconds since the deck was powered on.
system.reboot() 0.5 string Request a deck reboot. Requires confirmation.

#chrono

Time operations: timestamps, durations, delays.

Function Qn Returns Description
chrono.get_time() 0.1 number Current timestamp (seconds since epoch).
chrono.format_time(timestamp) 0.1 string Format a timestamp as "YYYY-MM-DD HH:MM:SS".
chrono.time_since(timestamp) 0.1 number Seconds elapsed since the given timestamp.
chrono.format_duration(seconds) 0.1 string Human-readable duration: "45s", "2m 30s", "1h 15m".
chrono.wait(seconds) 0.3 number Pause execution. Capped at 5 seconds. Returns actual duration. Abortable.
chrono.set_timer(duration, callback) 0.5 string Not yet implemented.

#Requires Network Adapter

These namespaces unlock when a network adapter (Wi-Fi Module, Mesh Radio, Quantum Communicator, etc.) is installed.

#net

Network transport: scanning for devices, establishing and dropping connections.

Function Qn Returns Description
net.scan_devices() 0.3 table[] Scan the local network. Returns a list of device tables, each with {network_id, name, node_type, connected}.
net.connect(network_id) 0.5 table Connect to a device by network ID. Returns {ok, connection_id} on success, {ok=false, error} on failure. Costs 1 bandwidth.
net.disconnect(connection_id) 0.2 table Drop a connection. Returns {ok} or {ok=false, error}. Frees 1 bandwidth.

Bandwidth: Each connection costs bandwidth. Total bandwidth is the sum of all installed network adapters. When bandwidth is exhausted, net.connect fails.

Network IDs: Every network node has a unique network_id — its fingerprint on the net. Network IDs are stable — the same node always has the same ID. They're the primary way to identify and reconnect to devices.

Persistence: Connections persist across script runs. A script can connect, finish, and a later script can use the same connection. Power-off drops all connections.

NetworkManager: Interactive network setup uses NeurOShell's nmcli command. The net namespace remains the scripting API, but it shares the same networking switches, radio availability, active connections, and per-adapter bandwidth. net.connect automatically chooses the enabled adapter with the most free bandwidth. If networking or every usable adapter is disabled, scans return no devices and connection attempts return an error.

#interface

Device interaction: once connected via net.connect, use interface to interact with the device. Every function takes a connection_id (from net.connect) as its first argument.

Function Qn Returns Description
interface.breach(connection_id) 2.0 table Attempt to break through a device's ICE. Required before send_command, read_data, or install_payload on secured devices. Returns {ok} or {ok=false, error}. See ICE section below.
interface.probe(connection_id) 0.5 table Query device capabilities. Returns {ok, commands, data_keys, accepts_payloads}. Works without breaching.
interface.send_command(connection_id, command) 0.5 table Send a command string to the device. Requires breach on secured devices. Returns {ok, command, result} or {ok=false, error}.
interface.read_data(connection_id, key) 0.3 table Read data from the device. Requires breach on secured devices. Returns {ok, key, value} or {ok, data}.
interface.install_payload(connection_id, script_name) 3.0 table Install a script as a payload on the device. Requires breach. Returns {ok, message} or {ok=false, error}.
interface.get_status(connection_id) 0.2 table Check connection state. Returns {ok, connected, alert_level, noise, trace_active, trace_remaining}. Works without breaching.

The three-step pattern: net finds and connects; interface.breach cracks the ICE; interface.send_command acts. A typical intrusion: scan → connect → probe → breach → send_command → disconnect.

Node-owned commands: Each device type defines its own valid commands and data. A door lock accepts "unlock", "lock", "log_clear". A camera accepts "disable", "loop_feed", "rotate". Sending an invalid command returns an error.

Payloads: A payload is a script from your deck installed on a remote device. Only some devices accept payloads (servers, terminals). Payload installation is the most expensive operation in NOS (3.0 Qn).

#ICE (Intrusion Countermeasures Electronics)

Devices with a security level above 0 run ICE. You must breach the ICE before you can send commands, read data, or install payloads. probe and get_status always work — you can look before you commit.

#Breach

Call interface.breach(connection_id) to attempt to crack the ICE. This is a blind commitment — you don't know how strong the ICE is until you try.

  • Success depends on your deck's crypto capability (encryption rating from your compute module + encryption boost from expansion cards like the Encryption Module or GPU). If your crypto meets or exceeds the difficulty, the breach succeeds.
  • Time depends on the ICE strength and your deck's processing speed. Stronger ICE takes longer. Better processors reduce the time.
  • Breach is per-session. It doesn't persist across script runs. Every script that needs to interact with a secured device must breach again.

#Alert Levels

Every device tracks an alert level during your session. Every action you take generates noise, and noise accumulates.

Level Name What happens
1 Passive Default. No logging. You're invisible.
2 Logging The device starts recording: your adapter's identity, timestamps, everything.
3 Alert Network security is alerted.
4 Intrusion A trace begins. You have 60 seconds.

#Noise

Every interface action generates noise. Better crypto hardware reduces how much noise you make. Noise decays during periods of inactivity — if your script waits between actions, noise drops.

Actions and their base noise (before hardware reduction):

  • probe: 0.5
  • send_command: 1.0
  • read_data: 0.3
  • install_payload: 2.0
  • Successful breach: 2.0
  • Failed breach: 10.0 (and alert jumps straight to 4)

#Trace

At alert level 4, a 60-second trace begins. Check with interface.get_status(conn) — it shows trace_active and trace_remaining.

Disconnect before the trace completes and your deck survives. But everything you did since alert level 2 is logged on the device — your adapter's identity, what commands you ran, when.

If the trace completes while you're still connected, the ICE captures your deck's data and fries it permanently.

#Hardware and ICE

Your deck's ability to breach ICE and operate quietly depends on installed hardware:

  • Compute module: Base encryption rating and processing speed
  • Encryption Module (exp_crypto): +10 encryption boost
  • GPU (exp_gpu): +5 encryption boost, +8 processing boost
  • AI Co-Processor (exp_ai_copro): +15 processing boost
  • Signal Processing Unit (exp_signal): +3 processing boost

A deck with no crypto expansion cards can only breach the weakest ICE. Corporate and military targets require dedicated hardware.

#mail

Messaging between deckers. Not yet implemented.

Function Qn Returns Description
mail.send(subject, body, to) 0.5 Send a message to another decker.
mail.receive() 0.3 Check for incoming messages.

#Requires Expansion Card or I/O Device

#device

Hardware management for connected peripherals. Not yet implemented.

Function Qn Returns Description
device.list() 0.2 List connected hardware devices.
device.connect(device_id) 0.5 Connect to a hardware device.
device.disconnect(device_id) 0.3 Disconnect from a hardware device.
device.send_command(device_id, command) 0.5 Send a command to a hardware device.
device.get_status(device_id) 0.3 Get hardware device status.

#Requires Encryption Module or GPU

#security

Cryptographic and intrusion detection operations. Not yet implemented.

Function Qn Returns Description
security.bypass_firewall(connection, method) 2.5 Attempt to bypass a firewall.
security.decrypt_data(data, key) 2.0 Decrypt encrypted data.
security.detect_intrusion() 1.5 Scan for intrusion attempts on your deck.

#Requires Storage Drive

#fs

File system operations on the deck's storage. Not yet implemented.

Function Qn Returns Description
fs.read(path) 0.3 Read a file from storage.
fs.write(path, data) 0.5 Write data to a file.
fs.list(path) 0.2 List directory contents.
fs.exec(script_name) 1.0 Execute a stored script.

#Script Size (Qn)

Every script has three size measurements, all in Qn (Quan):

  • Raw size: The script's size before assembly.
  • Compiled size: The storage space used after assembly.
  • Loaded size: The RAM used while the script is loaded.

What contributes to size:

Source Counts toward Cost
Namespace API call (e.g. net.connect) Raw, Compiled, Loaded Per-function (see tables above)
Control flow (if, for, while, elseif, repeat) Raw, Compiled, Loaded 0.05 each
Base script overhead Raw, Compiled, Loaded 0.2
Standard function (e.g. string.format) Loaded only 0.02 - 0.25 depending on function
String concatenation (..) Loaded only 0.15 each

Storage uses compiled size. RAM uses loaded size. A script must fit in both to be usable.

#Script Limits

Limit Value
Max output lines 100
Max line length 1,024 characters
Max chrono.wait() 5 seconds

A script stops if the deck overheats. Better cooling allows longer runs.

#Network Node Types

Devices in the world that scripts can scan and interact with. Each type has different commands and data.

Commands marked with * produce a visible effect in the room (other players can see them). Silent commands produce no room-visible output.

Node Type Security Commands Data Payloads
Security Panel 2 disable, enable, reset* log, status No
Security Camera 1 disable, loop_feed, rotate* feed, storage No
Server Rack 5 query, shutdown*, extract cpu_load, users_active Yes
Public Terminal 0 login*, browse, download uptime, network Yes
Electronic Door Lock 3 unlock, lock, log_clear status, last_access No
Vending Machine 0 dispense, restock, diagnostics inventory, revenue No

Visible effects occur when the script finishes. Repeating the same command on the same device during one run produces one visible effect.

#Example: Full Intrusion Script

-- Connect to a door lock, unlock it, clean the log, disconnect.

system.log("=== LOCKPICK ===")

local devices = net.scan_devices()
local target = nil

for i = 1, #devices do
    if devices[i]["node_type"] == "door_lock" then
        target = devices[i]
        break
    end
end

if not target then
    system.log("[!] No door lock in range.")
    return
end

local r = net.connect(target["network_id"])
if not r["ok"] then
    system.log("[!] " .. r["error"])
    return
end

local conn = r["connection_id"]
local info = interface.probe(conn)
if not info["ok"] then
    system.log("[!] " .. info["error"])
    net.disconnect(conn)
    return
end

system.log("[*] Commands: " .. table.concat(info["commands"], ", "))

local breach = interface.breach(conn)
if not breach["ok"] then
    system.log("[!] " .. breach["error"])
    net.disconnect(conn)
    return
end

local result = interface.send_command(conn, "unlock")
if result["ok"] then
    system.log("[+] Door unlocked.")

    local cleared = interface.send_command(conn, "log_clear")
    if cleared["ok"] then
        system.log("[+] Logs cleared.")
    else
        system.log("[!] " .. cleared["error"])
    end
else
    system.log("[!] " .. result["error"])
end

net.disconnect(conn)
system.log("[-] Clean exit.")