Core Concepts
Architecture
The tri-layer machine separates concerns chat collapses into one: Generation emits plans, Validation proves them safe, Runtime executes them durably. Each layer has one job; no layer is trusted to do another's.
The three layers
NILScript separates capability by design. Generation produces text but executes nothing. Validation forbids unsafe graphs without acting. Runtime owns side effects, and only through NIL. The core inversion: the part that is creative is not allowed to act, and the part that acts is not creative.
| Layer | Role | Analogy | Trust boundary |
|---|---|---|---|
| 1. Generation | NL intent → DSL (JSON DAG) | Compiler front-half | Produces text; executes nothing |
| 2. Validation | Static analysis before any side effect | Static gate | Rejects unsafe graphs |
| 3. Durable Runtime | Interprets the DAG, drives NIL per edge | Virtual machine | Owns side effects; persists state |
Layer 1 — Generation
The LLM is the compiler front-end, writing DSL programs. Models emit symbolic references ($.step_1.output.id) to values they cannot know yet — intent, not implementation. Three properties keep it safe despite an unpredictable model: no side-effect channel, self-healing input, and least power downstream.
Layer 2 — Validation
The validator runs before any side effect and rejects unsafe graphs through five checks: schema validation (additionalProperties: false), backward-only reference tracking, an acyclicity proof, whitelist enforcement against grant scopes, and type checking against verb profiles. On failure it returns structured diagnostics the generator reads to self-heal.
{
"valid": false,
"diagnostics": [
{
"code": "REF_UNRESOLVED",
"node": "step_3",
"path": "$.step_2.output.invoice_id",
"message": "step_2 (type: condition) produces no output; conditions route only.",
"hint": "Reference the action node that creates the invoice, or remove the dependency."
}
]
}Layer 3 — Durable Runtime
The runtime is the VM. It walks the validated DAG node by node, converting each action into a NIL PROPOSE then — after any approval — a COMMIT. Queries become QUERY; conditions route only; parallel and foreach fan out; await_approval blocks for a DECIDE. On terminal failure with on_error: compensate, it walks back via ROLLBACK.
Stateless chat → durable orchestration
A chat turn vanishes when the socket closes; a NILScript program persists. The runtime saves state after every node, so a crash between node 3 and node 4 resumes at node 4 — not at the sentence. Control flow is deterministic and replayable; non-determinism is quarantined into the NIL activities, the only place the outside world is allowed to be unpredictable. Every COMMIT carries an idempotency key, so a retry across a network edge replays the original outcome instead of acting twice.
A worked example
The sentence: “When a product drops below 5 units, reorder 50 from the default supplier, but only let me approve it if the order is over 1,000 SAR.” Generation emits a DSL program; validation admits it; the runtime executes. For the action node, the runtime sends a PROPOSE — which has no side effects:
{
"nil": "0.1",
"id": "msg_01H...",
"performative": "PROPOSE",
"grant": "grant_acme_agent",
"workspace": "ws_acme",
"timestamp": "2026-06-16T09:00:00Z",
"trace": "00-4bf92f...-00f067aa0ba902b7-01",
"body": {
"verb": "commerce.create_purchase_order",
"args": { "supplier_hint": "default", "sku": "SKU-1042", "quantity": 50 }
}
}The system resolves the facts itself. The order totals 1,250 SAR, crosses the threshold, and the profile floors the tier at HIGH — so it parks for approval:
{
"nil": "0.1",
"performative": "PROPOSAL",
"body": {
"outcome": "preview",
"tier": "HIGH",
"proposal_id": "prop_01H...",
"preview": {
"ar": "إنشاء أمر شراء: 50 وحدة من المورد «شركة الإمداد» بقيمة 1,250.00 ر.س",
"en": "Create purchase order: 50 units from supplier 'Imdad Co.' for SAR 1,250.00"
},
"resolved": { "supplier": "sup_88", "total": "1250.00", "currency": "SAR" }
}
}supplier_hint. The owner reviews out of band and issues a DECIDE; only then does the runtime COMMIT with an idempotency key, and the system emits a signed EVENT.What each layer guarantees
| Property | Guaranteed by | How |
|---|---|---|
| Can’t act on a hallucination | Generation + NIL | No side-effect channel; system resolves facts |
| Unsafe graphs never run | Validation | Static rejection before any commit |
| Same plan, same flow | Runtime | Deterministic walk; non-determinism quarantined |
| Crash doesn’t double-act | Runtime + NIL | Persisted state + idempotency replay |
| Every write is reviewable | Runtime + NIL | Preview from system facts; tiers; approval |