The Neuralang language
This document defines the Neuralang language: the tokens a conforming decoder must produce from gestures, the grammar those tokens must satisfy, what a program means, how it is written to text, and how a compiler hands it to an agent. It is a draft. Sections marked stable will not change before 1.0 without a deprecation cycle.
1. Overview
A Neuralang program is a sequence of tokens. Tokens come from two sources: gesture tokens, produced by a decoder from discrete hand gestures, and written tokens, produced by a handwriting decoder from strokes on a surface. The language does not distinguish how a token was produced; a keyboard is a valid decoder.
Programs describe work for an agent. A program has no expressions, control flow or types. It has functions, and a function has intents (what to do), checks (what must be true afterwards) and capabilities (what the agent may touch while doing it).
2. Lexical structure stable
2.1 Gesture tokens
A decoder emits exactly one of the following tokens for each recognised discrete gesture: fn { } intent verify allow deny run undo. The gesture-to-token mapping is fixed by §5 and is not user-configurable, so that a program written on one band reads the same on another.
2.2 Written tokens
A handwriting segment begins when the decoder detects writing and ends when the pen lifts for longer than 600 ms or a gesture token is produced. The segment's text becomes a single token whose class depends on the preceding keyword:
- after
intent: a string. The text is kept verbatim, trimmed of surrounding whitespace. - otherwise: a name. The text is lower-cased and internal whitespace is replaced with
., so “tests pass” becomestests.pass.
2.3 Undo
undo is a lexical token: it removes the previous token from the stream and is itself discarded. Two consecutive undos remove the whole previous statement. undo never appears in the text form.
2.4 Keywords
There are seven keywords: use fn intent verify allow deny run. use has no gesture and appears only in the text form.
3. Grammar stable
program := header* item* header := "use" ( "band" | "agent" ) name item := function | run function := "fn" name "{" statement* "}" statement := "intent" string | "verify" name | "allow" name | "deny" name run := "run" name name := segment ( "." segment )* segment := [a-z0-9_-]+ string := '"' character* '"'
A program is well-formed if it parses and every run names a function defined earlier in the same program or in a .nl file in the same directory.
4. Semantics
4.1 Functions
A function is a unit of work with a name. Running it produces one attempt by the agent on a branch named nl/<name>-<date>.
4.2 Intents
Intents are delivered to the agent in source order as a single brief. The compiler does not interpret them. An intent of the form "make no mistakes" is delivered like any other; whether it helps is between the wearer and the agent.
4.3 Checks
Each verify names a check. After the agent reports done, the compiler runs every check in order and the attempt succeeds only if all pass. A check is a built-in (tests.pass, lint.clean, build.ok, types.ok) or an executable under .nl/checks/<name> whose exit status is the result. A failed check leaves the branch in place and reports the first failing check.
4.4 Capabilities
Capabilities name what the agent's environment may do during the attempt: fs.read, fs.write, net.read, net.write, shell, secrets. allow adds one; deny removes one and takes precedence regardless of order. The starting set comes from .nl/policy.nl or, absent that, fs.read fs.write shell.
4.5 Run
run compiles the named function and sends it to the agent named by the use agent header, the session, or the project, in that order of precedence. A program with no run is valid and does nothing.
5. The chord table stable
| Gesture | Token | Definition |
|---|---|---|
tap.double | fn | Two index-to-thumb contacts within 350 ms. |
pinch.index | { | Index-to-thumb contact held 80–400 ms, then released. |
pinch.middle | } | Middle-to-thumb contact held 80–400 ms, then released. |
swipe.down | intent | Thumb swipe along the index finger, towards the palm. |
swipe.up | verify | Thumb swipe along the index finger, towards the fingertip. |
swipe.right | allow | Thumb swipe across the index finger, outward. |
swipe.left | deny | Thumb swipe across the index finger, inward. |
roll.cw | run | Wrist rotation of at least 45° clockwise (viewed from the elbow) and back. |
roll.ccw | undo | The same, anticlockwise. |
write | name · string | Index-finger handwriting on a surface, per §2.2. |
A decoder must report a confidence in [0, 1] with every gesture token and must not emit a token below 0.80. Gesture definitions follow the discrete-gesture set validated for generic (cross-person) surface-EMG decoding; see Research.
6. Serialisation stable
The text form is UTF-8, uses the extension .nl, and is produced by nl fmt. Headers come first, one per line. Each function starts on its own line; statements are indented two spaces; the closing brace stands alone. Strings use double quotes and escape \" and \\ only. Comments begin with # and run to end of line; they have no gesture and are preserved by the formatter.
A session log (.nl.log) is optional and records each token with its gesture, timestamp in milliseconds and confidence. It is never required to compile.
7. Agent protocol
The compiler sends one JSON object per run to the agent's standard input and reads JSON lines back. The object has the fields name, intents (array of strings), checks (array of names), capabilities (array of names), branch and cwd. The agent replies with {"status":"done"} or {"status":"blocked","reason":…}. The compiler then runs the checks itself; an agent may not declare a check passed.
{
"name": "ship",
"intents": ["add retry with backoff to the upload client", "make no mistakes"],
"checks": ["tests.pass", "lint.clean"],
"capabilities": ["fs.read", "fs.write", "shell"],
"branch": "nl/ship-2026-10-14",
"cwd": "/home/me/code/uploader"
}
Adapters for Claude Code and Codex CLI translate this object into each tool's own session format. The stdin target sends it verbatim.
8. Conformance
A conforming decoder emits only the tokens in §2 with the gestures in §5 and the confidence rule in §5. A conforming compiler accepts every program that satisfies §3, applies §4, and writes §6. A conforming agent adapter implements §7 and never reports a check result itself. The reference implementations of all three are in the neuralang repository, and the test suite under conformance/ is the authority where this text is unclear.