<nil>NILScript

Core Concepts

NIL — Wire Protocol

NIL (Network Intent Layer) is the lower layer: if the DSL is the program, NIL is the syscall interface. It defines an immutable envelope, a closed set of performatives, six HTTP endpoints, and refusals as first-class protocol outcomes.

The envelope

Every NIL message is immutable — eight fields, no more. additionalProperties: false rejects any unknown field at the door.

FieldMeaning
nilProtocol version (currently “0.1”)
idUnique message id
performativeOne of the closed performative set
grantThe scoped, budgeted authorization in use
workspaceTenant / isolation unit
timestampRFC 3339 creation time
traceW3C Trace Context traceparent
bodyPerformative-specific payload
envelope.json
{
  "nil": "0.1",
  "id": "msg_01HZX9Q7C3",
  "performative": "PROPOSE",
  "grant": "grant_acme_agent",
  "workspace": "ws_acme",
  "timestamp": "2026-06-16T09:00:00Z",
  "trace": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
  "body": {
    "verb": "commerce.create_product",
    "args": { "name": "Desert Honey 500g", "price": "85.00", "currency": "SAR" }
  }
}

Performatives — a closed set

NIL has a closed vocabulary: seven performatives on the speaker plane, plus DECIDE on the owner plane. The kernel is SEQRD-PC. Six map to HTTP endpoints; PROPOSAL is the synchronous response to PROPOSE and ROLLBACK.

PerformativeSide effectsPurpose
PROPOSENone (dry run)“What would happen if I did this?”
PROPOSALNoneThe answer: a preview or a refusal
COMMITYesExecute a previewed proposal
QUERYNoneRead state
STATUSNoneCheck a proposal or run
EVENTSigned, sequenced notification
ROLLBACKNoneRequest a governed reversal
DECIDEAuthorizesOwner plane: approve / reject / modify
Closed by design
The Speaker plane carries seven performatives; DECIDE remains the separate, credential-separated owner-plane performative. A profile cannot invent a new performative — the performatives are the grammar, the profiles are the vocabulary.

PROPOSE → PROPOSAL

The two-phase core. PROPOSE has no side effects; the system answers with a PROPOSAL — either a preview or a refusal. The preview is rendered from system-resolved facts, never from the agent’s hint.

PROPOSAL — preview
{
  "nil": "0.1",
  "performative": "PROPOSAL",
  "body": {
    "outcome": "preview",
    "proposal_id": "prop_77c1",
    "tier": "MEDIUM",
    "preview": {
      "ar": "إنشاء فاتورة لـ «شركة آكمي» بمبلغ 4,200.00 ر.س",
      "en": "Create invoice for 'Acme Corporation' for SAR 4,200.00"
    },
    "resolved": {
      "customer_id": "cust_3391",
      "customer_name": "Acme Corporation",
      "amount": "4200.00", "currency": "SAR"
    },
    "modifiable": ["discount_pct"],
    "expires_at": "2026-06-16T09:15:01Z"
  }
}

COMMIT

COMMIT references an existing proposal_id and carries an idempotency key. A retried COMMIT with the same key is a no-op that replays the original outcome with replayed: true — no second invoice.

COMMIT
{
  "performative": "COMMIT",
  "body": {
    "proposal_id": "prop_77c1",
    "idempotency_key": "create_invoice@run_5530"
  }
}

QUERY & STATUS

QUERY is read-only — no side effects, no proposal, fresh business truth. STATUS checks the state of a proposal or a run, which matters for parked HIGH and CRITICAL proposals awaiting a decision.

EVENT

The system pushes signed, ordered notifications following Standard Webhooks conventions. Each carries a monotonic sequence number per workspace for dedup and an HMAC-SHA256 signature. A sequence gap means a missed event; a repeat means dedup.

ROLLBACK

The lifecycle-closing primitive. ROLLBACK requests a reversal of a prior committed action; it does not execute. Like PROPOSE it has no side effects — the system answers with a PROPOSAL (a compensation preview), which is then COMMITted like any other action. So “no silent write” holds for free. The system resolves the verb’s reversibility tier:

  • REVERSIBLE — a clean inverse (create_productdelete_product).
  • COMPENSABLE — an offsetting forward action (record_paymentprocess_refund).
  • IRREVERSIBLE — refused honestly with code IRREVERSIBLE; the default for any unmarked verb.

Verbs and profiles

A verb is a domain action — commerce.create_product, services.create_invoice — that names intent, not implementation. Whether it becomes a SQL insert, a GraphQL mutation, or three SOAP calls is the system’s problem. A verb is standard only if it has a published profile, which fixes its arg schema, tier floor, modifiable facts, resolution rules, and localized preview templates.

Same verb, same preview, any backend
Because the profile owns resolution and preview rules, two backends exposing commerce.create_product present the same preview to a human and accept the same args from an agent. That is what makes NIL a port, not just an API.

Refusals are outcomes

The most important design decision in NIL: a refusal is a 200 OK PROPOSAL, not an HTTP error. The system decided not to proceed, and that decision is data the agent and human can reason about. An AMBIGUOUS refusal returns up to eight candidates rather than a guess:

PROPOSAL — refusal
{
  "performative": "PROPOSAL",
  "body": {
    "outcome": "refusal",
    "code": "AMBIGUOUS",
    "message": "3 customers match 'Acme'. Choose one.",
    "candidates": [
      { "id": "cust_3391", "label": "Acme Corporation", "hint": "Riyadh · 41 invoices" },
      { "id": "cust_7720", "label": "Acme Trading Est.", "hint": "Jeddah · 2 invoices" },
      { "id": "cust_9015", "label": "Acme Holdings", "hint": "Dammam · 0 invoices" }
    ]
  }
}
CodeMeaning
AMBIGUOUSHint matched >1; returns ≤8 candidates
UNRESOLVEDHint matched nothing
INVALID_ARGSArgs failed the profile schema
POLICY_DENIEDNo grant authorizes the action
BUDGET_EXHAUSTEDGrant budget spent (fail-closed)
EXPIRED / SUSPENDEDProposal/grant expired, or actor suspended
IRREVERSIBLEROLLBACK targeted an effect with no reversal

Standards alignment

NIL deliberately reuses existing standards instead of reinventing them:

StandardUsed for
W3C Trace ContextThe trace field
BCP 47Locale tags for previews
ISO 4217Currency codes
RFC 6750Bearer tokens
RFC 9457Problem Details (transport errors)
Standard WebhooksSigned EVENT (HMAC-SHA256 + sequence)

NILScript is an open standard, stewarded by the Wosool project. The spec is extracted from running code.

Draft standard v0.3.0 · 0.x stage · NIL wire 0.1 · DSL 0.1