neural/rune/docs/explanation/acts-and-the-ward.md

acts and the ward

rune evaluation is pure. The 18 Nox patterns cannot touch the world — no file written, no graph read, no pixel drawn. So how does a rune program do anything? Through an act.

an act is a request, not a deed

When the interpreter reaches an act — opcode 16 with an act tag (emit, query, link, seal, subscribe, host) — it does not perform it. It hands the act to a host: (act, args, caps) → result. The host performs the effect and returns a noun, which the interpreter splices back in and continues.

rune program ──evaluates──> act request ──> host performs ──> result ──> continue

This is the whole trick. The evaluator stays pure and provable; the host is the single, explicit place where consequence happens. A pure eval (no host) simply no-ops every act, so the same program is inert or active depending only on which host runs it.

The CLI demonstrates this: rune eval 'emit(text("hi"))' runs with a host that collects emitted chunks and prints them. Swap the host and the same emit draws to a terminal, a log, or nothing.

the ward performs the acts

rune defines acts but does not decide whether they are allowed. That belongs to cyb, in a boundary called the ward (see cyb/root/ward.md). The ward is to acts what prysm is to rendering: one runtime-blind boundary that many runtimes feed. It is not a rune feature — Nox, rune, Inf, glia, and wysm all route their acts through the same ward.

The program carries its granted capabilities in the subject's ~caps slot (axis 30). The interpreter reads ~caps before calling the host, so the host — the ward — can check the act against the rights the program actually holds. A program can only narrow its own caps, never widen them.

program ──act + ~caps──> ward.perform(act, args, caps) ──> result | denied

what is built today

The act mechanism is real: the Host trait, eval_with_host, and the emit/query/link/seal/host act tags are implemented, and the cyb terminal performs emit live. The ward as an enforcement boundary — gating acts on ~caps, the deny-by-default policy, the prompt UX — is designed and documented but not yet wired; today the terminal host performs emit ungated. The seam exists, so adding the gate is a contained change.

see also

  • execution.md — pure, reactive, and host modes
  • cyb/root/ward.md — the permission boundary in full

Graph