Spaces
The five core space types and the design principles each one enforces.
Spaces (@) are the primary topological units of Anglish. Each space defines a bounded context where agents operate, tasks execute, and data is emitted, consumed, or transferred.
Every space declares a type tag. The tag is a contract with the compiler: it conveys expected behaviour (user-facing, sensor-bound, logic-driven), supports static validation, and guides runtime placement across edge, cloud, or client.
Hybrid behaviour is expressed by composing across types using $use(), never by hand-rolling a multi-purpose space.
:UI — interactive surfaces
A :UI space is a declarative surface for dashboards, input forms, and control panels. The author describes intent — layout, validation, flow — through vibe blocks; the compiler synthesises the runtime UI logic and rendering (HTML/CSS/JS or native components).
Design principles.
- Event-driven. All behaviour is triggered by explicit UI events (
%onEnter,%onSubmit,%onError). No implicit background processing. - State via binding. Inputs and outputs are bound to named data objects (
%formData). - Stateless rendering. Rendering does not persist state between invocations; durable state must live in
:DATAvia$data_reader/$data_writer. - Separation of concerns. UI handles presentation and event capture only; validation, transformation, and persistence belong in
:FUNCor:DATAspaces. - Explicit composition. Multi-panel UIs are composed via
$use()or subspaces — never implicit inclusion.
Standard tasks.
$ui_reader(out=<dataObject>)— captures user inputs with sources, constraints, and validation rules. Always exactly oneout=.$ui_writer(in=<dataObject>)— renders feedback, success messages, error prompts, or dynamic content. Always exactly onein=.
:IO — sensors, devices, streams
An :IO space anchors a program to physical devices and streams: sensors, cameras, microphones, sockets, actuators. Authors specify what to capture, when it flows, and how to handle faults — without embedding driver code.
Design principles.
- Event/stream first. Behaviour is driven by explicit lifecycle and stream events (
%onEnter,%sensorUpdate,%onError). - Boundary, not brain.
:IOspaces terminate at the device or network boundary. Transformation, validation, or reasoning are delegated to linked:FUNCor:AGENTICspaces. - Stateless between events. Each read/write is stateless; durable state externalises through
:DATAvia explicit$data_reader/$data_writer. - Explicit flow control. Sampling rates, backpressure, and retry policies are described in vibe blocks; implicit buffering is discouraged.
Standard tasks.
$io_reader(out=<signalStream>)— ingests or polls external signals. Oneout=.$io_writer(in=<controlSignal>)— emits control or acknowledgement messages. Onein=.
:DATA — persistence
A :DATA space is a device-agnostic, network-aware dataspace behaving like a logical folder hierarchy or object store. Authors declare what to store, version, or replicate, without prescribing the backend.
Design principles.
- Path-driven access. All reads and writes require explicit
path=; absent paths are compile-time errors. - Stateless operations. Each
$data_reader/$data_writercall is stateless; versioning, retention, and replication policies are declared, not implicit. - Separation of storage and logic.
:DATAspaces persist and serve; transformation lives in:FUNCor:AGENTIC. - Observable IO. Emissions like
%dataUpdated,%onEnter,%onExitare the only drivers of work. - Backend portability. The same declaration must target local files, object stores, or key-value stores without changes.
Standard tasks.
$data_reader(path=<spec>, out=%blob)— retrieves a blob or listing from the path.$data_writer(in=%blob, path=<spec>)— persists or updates content at the path.$list(prefix=<spec>, out=%entries)— enumerates keys/paths matching a prefix.$metadata_reader(path=<spec>, out=%meta)— reads metadata.$metadata_writer(in=%meta, path=<spec>)— updates metadata.$delete(path=<spec>)— removes the object at the path.$version_reader(path=<spec>, out=%versions)— returns available versions for a versioned object.
:FUNC — deterministic logic
A :FUNC space handles incoming work using deterministic functions only — no LLMs. It is stateless across invocations; durable state must flow through a :DATA space.
Design principles.
- Determinism. Routing and execution are fully deterministic. Selection policies are expressible as clear conditions in vibe blocks.
- Statelessness. No cross-invocation memory. State flows through
:DATAspaces withpath=on every read/write. - Separation of concerns. Routing lives in
$func_main; business logic lives in space-native tasks.
Standard tasks.
$func_main— mandatory. Deterministic router/selector for incoming work. Exactly onein=.$fallback— optional. Handles unroutable or invalid work.
:AGENTIC — LLM-routed
An :AGENTIC space handles incoming work by engaging an LLM-backed router ($agentic_main). This is for free-form, ambiguous, or natural-language requests where intent must be inferred.
Design principles.
- LLM-driven routing. The selector matches incoming requests to one or more available tasks, potentially re-phrasing or disambiguating.
- Statelessness. No cross-invocation memory. Durable state flows through
:DATAvia explicit$data_writercalls. - Mixed determinism. Routing is model-driven; invoked tasks can be deterministic or agentic.
- Fallback behaviour. Unmatchable or low-confidence routes are handled by
$fallbackor a user-defined error-handling task. - Tool schema awareness. The LLM router has access to the signatures and descriptions of all tasks in the space.
Standard tasks.
$agentic_main— mandatory. Uses an LLM to interpret the request and select tasks to run. Exactly onein=.$fallback— optional. Handles unroutable or low-confidence work.