“A value changed” is not one kind of operation in an interface. AUP distinguishes reading data, writing data back, projecting data into a prop, storing UI-local state, and handling a user event. Choose the contract first so the renderer, AFS scope, and tests know who owns what.
Four data/state relationships
| Form | Current meaning | Do not infer |
|---|---|---|
src | A read-only AFS data path | Automatic write authority |
bind | A read/write AFS binding, often used by input | Every path is readable and writable |
propBind | A server-managed read-only dotted prop path → AFS path binding | A renderer itself calls AFS or manages subscriptions |
state | A UI-local state object | All state is necessarily client-only or persistent |
propBind resolves its initial value before first render and updates props through a patch when its source changes. Input validation is explicitly marked as client-only transient state; the lifecycle of other state must be accepted against the behavior of its app/renderer rather than assumed from one blanket rule.
The current DSL can compile from "path" to src, and accepts bind=..., propBind={...}, state={...}, and events={...}. Path validation rejects javascript: and ..; that is not a promise that an arbitrary AFS path receives access authority.
Three results of an event
An AUPEvent can:
- Call an AFS action with
execand optionalargs. - Update a node's
src,props,state, oreventsthroughtarget+set. - Perform client-side browser-level URL navigation through
navigate.
The current preferred named-page navigation sets target to _root and uses set: { page: "name" }. The older JSON form page: "name" is deprecated. New DSL can use -> page details, which compiles to the preferred root/set form.
These DSL snippets use shapes accepted by the current parser:
button open "Open" primary -> page details
button load "Load" primary -> set viewer src "/items/42"
button bump "Bump" primary -> set dial state {value: 7, dirty: true}
action -> exec "/.auth/logout"
action -> navigate "/.well-known/service/login"-> is click sugar for buttons/actions. Other nodes should explicitly use on <event> -> .... When one update needs a compound set, such as src and props together, use complete events={...} rather than expecting one-line sugar to express every combination.
Accept observable behavior
First verify one thing: does an input or action produce the intended patch or page change? Then verify that an AFS action runs only in the correct caller scope. Finally inspect renderer loading, validation, or animation state. Collapsing all three into “the button can be clicked” hides errors in read/write authority, update targets, and navigation semantics.
Read Sessions, patches, and scenes next for how updates propagate through an interactive session.