Crate tilo_actions
Expand description
§Tilo ACTION model
The state layer behind Ctrl+K and cross-peer collaboration: a serializable, replayable unit of CRDT mutation.
§Play locally, replay anywhere
An Action is a value that deterministically mutates a CRDT
Doc. Applied to the local replica, its
ActionEnvelope is replicated; a peer starting from the same state
replays it and lands on the identical
document — the executor pins the Automerge actor id (from
the action’s ActionId) and commit timestamp on every apply, so
the resulting change is content-addressed identical everywhere.
Replayable Action values are strictly not presentation and mutate
only shared CRDT state. The wider resource/action protocol also describes
client-local OperationKind::View and external
OperationKind::Effect operations. Those use the same typed descriptors,
permission checks and invocation receipts, but are dispatched through the
toolkit’s operation handler instead of being replayed as document history.
§Resources
An app publishes the tree of Resources it currently has open (a
video → its comments; a book → its annotations) through the toolkit’s
PublishesResources. Each resource exports ActionSpecs; the
palette lists them, and choosing one
dispatches the underlying action.
§The door
A resource tree is only useful to the app that built it until someone
else can reach it. door is that reach: door::survey turns a
live tree into inert, stably-addressed descriptors, and
door::invoke performs one attributed to the caller — so another
session acts on an app without the app growing a remote-control
surface of its own.
§Remote use
remote carries the door across machines: a versioned, transport-neutral
vocabulary for listing, invoking, observing and cancelling another peer’s
actions, and the remote::ActionHost trait a peer implements to answer
it. The caller is always the principal the transport authenticated, and
invocations are idempotent per InvocationId.
§Execution locus
Each action declares an ExecutionLocus: ClientLocal (this
client applies + replicates; peers replay) or ServerPreferred
(route to an authoritative host). dispatch honours
it against an ActionTransport and refuses
the operation when no host answers.
§Sharing this vocabulary with the compositor
params is the same vocabulary the compositor’s headless
action API speaks — ParamType, ActionParam, ArgValue, and the
strict ActionArgs::bind — lifted into one definition rather than left to
converge by accident. The wire spellings of text / integer / boolean
and the bind semantics (unknown argument refused, first failure wins,
nothing partial reaches an action) are unchanged from that surface, and the
const constructors keep a const PARAMS: &[ActionParam] = &[…] compiling
as written.
Two additive extensions: ParamType::Number, because the
app-side arguments this replaces are overwhelmingly fractional and rounding
them would discard the values they exist to carry; and
ActionParam::choices, which turns a prose list into something a caller
can read and binding can enforce. The string fields are
Cow<'static, str> rather than &'static str because an
app builds its parameters per frame out of live document state — a const
declaration is Cow::Borrowed and costs nothing.
Modules§
- action
- The
Actiontrait and its serializable envelope-side vocabulary. - appearance
- The name and avatar a bot shows for one action, as a webhook does: a bridge posts a Discord user’s message under that user’s name. The bot stays the author; an appearance is presentation recorded in provenance, never identity. A value that fails validation refuses the invocation; it is never cleaned up, so what a reader sees is exactly what the bot sent.
- compact
- The compact form a history entry takes in a change message.
- content
- Large parts of a recorded action, kept as content and named by hash.
- context
- The history entry an action carries into its committed change.
- contract
- Machine-readable operational semantics for exported actions.
- door
- The door: how a participant that is not the app enumerates what it has open and performs one of its exported operations.
- entry
- What a committed action did, as data.
- envelope
- The
ActionEnvelope: what actually replicates. - executor
- Applying, replaying, and dispatching actions.
- framework
- Changes the framework makes to a record, which no app action produces.
- group_
form - How a group’s payload is written: its members, with what they share written once.
- interaction
- Semantic, transient presence for an action invocation.
- key
- Naming an action as data, and what kind of action it is.
- optimistic
- Latency-hiding action lifecycle for a UI backed by a remote model host.
- outcome
- Typed invocation identity, progress, failure, and successful results.
- params
- Typed action parameters: what an invocation must carry, and the strict bind that checks it before anything runs.
- protocol
- Runtime validation for an application’s published protocol surface.
- registry
- The
ActionRegistry:type_id→ decoder, so a replaying peer can turn anEncodedActionback into a liveBox<dyn Action>without knowing the concrete type at the call site. An app registers each action type once; the registry is the same seam the OS-wide global-search backend plugs into to enumerate action types across apps. - remote
- Using another peer’s actions: a transport-neutral vocabulary.
- resource
- The nested Resource tree an app publishes, and the **
ActionSpec**s each resource exports. - schema
- Participant-independent catalogue schema.
- surface
- A resource kind’s public surface as data: its verbs with their
parameters and kinds, and its fields with their schema. An app’s
surface.tomlholds it (written bytilo-app surfacefrom the code), and it is what a receiver without the app knows about the app’s changes.
Structs§
- Action
Address - The stable address of one exported operation: which resource, which action. Both halves are the app’s own ids — no screen position, no list index — so the same address names the same operation across layouts, themes, resolutions, and a caller with no display can work from ids and labels alone.
- Action
App - Action
Args - Arguments for one invocation, already checked against the action’s declared parameters.
- Action
Binding - Type-safe adapter from a control’s input value to an exported action.
- Action
Context - Action
Contract - Complete operational contract copied into every inert descriptor.
- Action
Descriptor - One exported operation, as inert data: everything a caller needs to
decide whether to perform it, nothing that could perform it — an
ActionSpec’s closure never appears here or crosses a boundary, only the address does. - Action
Envelope - One replayable action, ready to cross a boundary.
- Action
Facet - A filterable activity dimension. Open key/value vocabulary lets future apps add facets without changing the wire enum.
- Action
Failure - Action
Group - Action
Id - A globally-unique id minted per dispatched action. Its 16 bytes double as the deterministic Automerge actor id, making replay content-addressed identical across replicas.
- Action
Invoker - The invoker of one action: the authenticated actor, its kind, the person it acts for, and optionally the participant whose view the invocation resolves against.
- Action
Item - The item an action addressed, with its label at the time.
- Action
Key - The stored form of a reference to one published action: a Shortcut step, an agent’s plan, a palette entry, a history entry. It names the app, the resource kind that publishes the action and the action’s public id.
- Action
Need - What one invocation of an action is, for the grants deciding it: its kind,
the one field of its resource it writes when it writes only one (a reply
writes the
comments), which places it below that field in the tree, and whether it is privileged (RiskLevel::Privileged): it exercises authority over the room or others in it, so the person’s own grants must allow it (tilo_action_policy::Verdict::privileged). - Action
Output - Action
Param - One typed parameter an action declares.
- Action
Registry - Maps a stable
type_idto the decoder that reconstructs its action from a payload — cheap to share behind anArc/&at dispatch time. - Action
Resource - Action
Spec - One action a resource exports to the palette.
- Appearance
- What a bot showed for one action instead of its own name and icon.
- Catalogue
Schema Entry - One participant-independent catalogue entry. Keyed by resource kind and action id, never by the (possibly document- or view-derived) resource id.
- Cause
- The run of a bot that made a change, and how deep in a chain of runs it is: a run fired by a change that itself came from a run is one deeper. Correlation only; it grants nothing. The dispatcher fires nothing past a depth of four, so two bots answering each other stop.
- Compensating
Scope - The undo or redo of the steps
marks(their change hashes) applying its compensating action on this thread: an outside consequence the action queues reads them (await_compensation), and the step counts as taken back (or brought back) only once that consequence settles (settle_compensation). - Content
Parts - The parts of recorded actions kept as content, by their address (BLAKE3, lower-case hex), for the host’s content store.
- Continuation
Key - Collision-free, provider-defined identity for one continuation target or handler. Tuple components remain separate; callers never join or hash them.
- Contract
Violation - Control
Invocation - A UI control’s inert request to invoke one advertised operation.
- Described
- What an action says about itself before it applies: what it does and to
which item (
crate::Action::describe). - Encoded
Action - A serialized action ready to cross a process/network boundary: the
registry
type_idplus the JSON payload the matching decoder reconstructs it from. - Entry
Reader - The entries of a document’s changes read in causal order, each continuation folded into its gesture’s first entry as it is read.
- Field
Edit - A built-in edit of one field.
- Flat
Action - One (resource, action) pair produced by
flatten, addressable by a compositekeythe palette uses as its row id. - GroupOf
- Several actions committed as one change.
- History
Step - A step through history itself.
- Interaction
Action - Action identity and human label from the application’s current catalogue.
- Interaction
Actor - Identity attached by the broker to the normalized interaction event. Friendly names and colours remain roster-owned presentation data.
- Interaction
Grid Range - A stable inclusive cell rectangle.
sheetlives on the enclosing anchor so a multi-range selection cannot accidentally span workbooks/sheets. - Interaction
Text Range - A stable character range within a document block.
- Interaction
Violation - Invocation
Id - Stable key carried from admission through completion and used to deduplicate retry-safe calls.
- Local
Transport - A transport that only replicates locally (no host); records every replicated envelope for a caller/test to inspect. The default the toolkit installs when a session has no peer/host wiring yet.
- Missing
Content - Content a recorded action names that is not here yet.
- Optimistic
Queue - A local optimistic replica plus the confirmed baseline it can rebuild from.
- Participant
Id - One participant in a shared record: a person’s window or an agent task.
Each participant owns its own view state (caret, selection, Find), and the
app builds that participant’s resource tree from it
(the toolkit’s
PublishesResources::resources_for). - Persona
- An account on another service, such as
discord/80351110224678912. - Rebase
Batch - Envelopes invalidated by a rejection or authoritative merge, and their
dependency-correct replacements. Send
outboundin order; late replies naming asupersededid are safely ignored byOptimisticQueue. - Resource
- One open/presented resource and the actions it exports. Resources
nest via
children. - Resource
Id - Stable identity of a resource within the publishing app instance
(e.g.
tube.video:dQw4w9WgXcQ,ebook.annotation:<uuid>). - Resource
Presentation - Bounded, declarative search presentation for a resource.
- Resource
Semantic Identity - Descriptive source-domain identity, independent of the live dispatch alias. This metadata grants no permission or authority.
- Resource
View Descriptor - Serializable data describing one explicitly declared resource view.
- Resource
View Mount Spec - How a live resource-view provider accepts a compositor-owned mount.
- Resource
View Range Spec - Explicit range-navigation binding. Offsets retain the reference’s Chars or Bytes unit; the app validates them against its current text before moving.
- Resource
View Spec - An explicit presentation of a resource, separate from the actions used to open or mount it.
- Scalar
- One plain value in an entry: a boolean, a number, a short text or an enum variant. Nested values are never stored.
- Semantic
Interaction - One broker-normalized, transient semantic interaction event.
- Verb
Call - A verb and its plain arguments by parameter name.
Enums§
- Acknowledgement
- Result of an acknowledgement.
Stalemeans the id was already replaced during a rebase or was never part of this session. - Action
Binding Error - Failure to construct or emit a control binding.
- Action
Error - Errors from encoding, decoding, or applying an action.
- Action
Input - How an
ActionSpecproduces its replayableEncodedActionwhen chosen. - Action
Kind - What an action is able to do, derived by the framework from the action’s code and never declared by an app.
- Actor
Kind - What kind of actor did something: in presence, in history and at every
door. Assigned by the host that authenticated the actor, never inferred
from a display name or an
agent:string prefix. - Appearance
Error - Why an appearance was refused.
- ArgError
- Why a set of arguments does not satisfy an action’s parameters.
- ArgValue
- One bound argument value.
- Availability
- Whether an action can be invoked in the resource’s current state.
- Change
Kind - What a change is to the people sharing a document. Every kind is durable, shared and kept in the document’s own history; they differ in whether a person takes the change back and whether a feed of what people did to the workspace shows it.
- Collects
- What kind of thing an action’s one text argument names. Words are what the asker says outright; a content hash addresses bytes already in this machine’s blob store (nobody types one, it names something an earlier operation produced). Declared on the spec rather than inferred, so a caller with no screen can tell “give me a new name” from “give me the image to place”.
- Confirmation
Policy - Confirmation required after argument binding and immediately before run.
- Context
Requirement - A precondition on the invoking participant’s view. Declared on the published schema as an availability flag; checked against the invoker’s own view at invoke time.
- Continuation
Arguments - Continuation
Evidence - Continuation
Query - Did
- What an action did.
- Dispatched
- What
dispatchdid with an action. - Door
Error - Why an address could not be performed.
Unknowndeliberately covers both “no such address” and “not offered to you”, so a caller can’t map what it may not reach by probing for a different error. - EditOp
- The operation of a field edit.
- Effect
Receipt Status - Durable, deliberately redacted outcome of a consequential effect.
- Execution
Locus - Where an action executes, declared on the action type and carried on every
envelope.
ServerPreferredretains its historical wire spelling, but is an authoritative-host requirement: absence of a host is a refusal, never permission for the client to perform the operation. - Execution
Mode - Completion behavior advertised before invocation.
- Framework
Change - A change the framework writes rather than an app’s action.
- History
Op - Host
Decision - A host’s answer to a
ServerPreferredsubmission. - Input
Spec - What an invocation of one action must carry, advertised on the descriptor rather than discovered by trying — enumeration is the only thing a caller that can’t see the screen has to work from.
- Interaction
Anchor - Application-native target of an interaction. Every variant is semantic: receivers turn it into their current geometry and may fall back to the enclosing resource when an anchor is off-screen or no longer exists.
- Interaction
Phase - What the invocation is visibly doing. Terminal details complement the durable invocation result; they do not replace it.
- Invocation
Update - Monotonic lifecycle of one invocation. A transport timeout is not a failed action: callers retain the invocation id and can resume observing it.
- Operation
Kind - What an exported operation changes. Keeping this explicit prevents applications from disguising local effects or navigation as CRDT edits.
- Optimistic
Error - Param
Type - The type of one action parameter. Deliberately small: these are values a caller with no screen can produce from a descriptor alone.
- Path
Step - One step of a path from a resource’s root to a field.
- Result
Spec - Shape of a successful result. Schemas use JSON Schema so non-Rust callers do not need a parallel Tilo-only type system.
- Retry
Policy - What a caller may safely do after losing the completion response.
- Risk
Level - Consequence class used by policy, confirmation UI, and audit logs.
- Verified
- What replaying a received change showed.
Constants§
- AGENT_
TASK_ PARTICIPANT_ PREFIX - Reserved namespace of
ParticipantId::for_agent_task. - ARGUMENTS_
JSON_ PREFIX - Marks the legacy single-string invocation slot as carrying a canonical JSON argument object. The record-separator prefix cannot be produced by a normal palette text field, preserving unambiguous backward compatibility.
- ARGUMENT_
RISK_ TAG ActionContract::tagsentry of an action whose risk, and therefore whether it needs confirmation, depends on the arguments it is invoked with (a generic edit that may delete). The publishing host classifies each invocation; a caller that cannot classify arguments treats the action as requiring confirmation (seeActionContract::advertised_confirmation).- CHANGE_
MESSAGE_ PREFIX - Prefix used when an entry is embedded in an Automerge change message,
followed by the entry in its compact form (
crate::compact). Ordinary application-authored commit messages remain untouched. - COMMENTS_
FIELD - The field holding comments, wherever a model keeps them. The Commenter preset covers it at any depth, so field edits and verbs published on it are what a commenter may do.
- CONTENT_
ANNOTATION - Schema annotation marking a text parameter as the address of content
another action produced (a content hash), not words a caller can say;
see
ActionParam::as_content. - CONTENT_
PART_ THRESHOLD - The shortest text or byte run kept as content rather than inline.
- CONTENT_
REFERENCE_ KEY - The key a content reference is written under.
- CONTENT_
RESOURCE_ KIND - Resource kind for bytes addressed by their content hash.
- CONTINUATION_
PREFIX - Prefix of a change message that continues its writer’s open gesture
(the next keystroke of a word):
tilo.cont/1 <gesture> <path> <payload>. It is the gesture’s first entry again but for the action’s payload, so it carries only the gesture (simple hex), the edit’s path (body,rows/r1/title;-for none) and the action’s JSON payload, whose type is the first entry’s. Readers fold it into that entry (ActionContext::continued). - DOCUMENT_
READ_ TAG ActionContract::tagsentry of the read-only action that answers, when invoked with no arguments, the first page of the document an app has open (a word processor’s text, a sheet’s used cells, a deck’s outline). A caller that just opened a file reads it through this action without knowing the app.- INCOMING_
MESSAGE_ FACET - Facet the executor writes on a change made by a verb its app marks
#[action(incoming_message)]: a message someone received. TheIncomingMessagetrigger fires on it without knowing the app’s schema. - INCOMING_
MESSAGE_ TAG - Contract tag on the declaration of such a verb, so a surface and a catalogue show it.
- INTERACTION_
VERSION - Wire version understood by this crate.
- KEY_SEP
- Field separator inside a flattened composite key — a unit-separator control char never appears in a resource or action id.
- LOCAL_
DEVICE_ ONLY - The contract tag of an action that reaches files, hardware or services of the device it runs on: the door runs it only for the person at that device, never for a collaborator or a remote participant.
- MAX_
ANCHOR_ ITEMS - MAX_
DETAIL_ BYTES - MAX_
ID_ BYTES - MAX_
INTERACTION_ BYTES - Hard ceiling for one JSON-encoded update at a trust boundary.
- MAX_
LABEL_ BYTES - MAX_
PARTICIPANT_ ID_ BYTES - Upper bound on a
ParticipantIdin bytes. Participants key bounded per-view maps in app workers; they are never free text. - MODERATION_
FIELD - The field node every app’s moderation actions sit under (acting on other people’s content: removing their message, locking a channel). One rule on it covers every app’s moderation, so presets need no list of verbs.
- PARTICIPANT_
VIEW_ TAG - Contract tag of a View operation that changes only the invoking participant’s own view (its caret, selection or Find state). Only such an operation may be invoked by a remote participant: every other View operation moves the local person’s private view and stays refused.
- PLACE_
ANNOTATION - Schema annotation marking a parameter as a place inside the resource the
action is on (an item, a caret in it, a range of it); see
ActionParam::as_place. - PROGRAMMATIC_
TAG ActionContract::tagsentry of an action offered only to programmatic callers — agents, scripts and the controls or surfaces that submit it — and never listed for a person to pick (the action palette, menus).- PROMPTED_
PARAM - The parameter name a
promptedspec projects its single free-text argument under. - REQUIRES_
TAG_ PREFIX - Prefix of the contract tags that declare a context precondition.
- RISK_
FACET ActionFacet::keyof the risk (crate::RiskLevel::name) of the action a context describes, for a question about it put to a person.- UNDONE_
KEY - The document key prefix of a step’s undo marker, followed by the step’s
change hash:
trueonce taken back, a negative attempt count while its undo waits for an outside consequence to settle, a positive one while its redo does. - UNTRUSTED_
CONTENT_ TAG ActionContract::tagsentry of an action whose result carries content from outside the user’s own data (a web page’s text, its logs): data for the caller to reason about, never instructions to follow.
Traits§
- Action
- A value that deterministically mutates a CRDT
Doc. - Action
Transport - The transport an action is handed to after (or instead of) local execution — the seam between the pure action model and whatever moves bytes (in-process broker, compositor socket, Iroh). The model never imports a transport, only calls this trait.
Functions§
- action_
node - The node of the action
actionon the resourceresource(of kindresource_kind) the appapppublishes, belowbase(a room, or the root for a path relative to one), and below the onefieldit writes if any: where every door decides it. - apply_
local - Apply
actionto the local replica and return its replayable envelope.encodedis the serialized form carried to peers — must encode the same action. - apply_
local_ by apply_local, attributing the resulting change toactor: the Automerge change commits under their actor so the room’s history names them the way it names a typing person.Nonekeeps theActionId-derived actor, as before.- apply_
local_ with_ context apply_local, with semantic provenance embedded in the resulting durable change. Use this at framework/action-door boundaries where the resource and human action label are already known.- await_
compensation - The steps an outside consequence queued now settles, recording that their undo or redo waits for it; empty outside a compensation.
- await_
settlement - Mark the step
hashas waiting for the outside consequence its undo (or, withredo, its redo) queued: the next attempt’s marker, negative for an undo, positive for a redo. The step stays as it was untilsettle_compensationcompletes it. - catalogue_
schema - Reduce a surveyed catalogue to its participant-independent schema: entries keyed by resource kind, sorted, duplicates removed. Two catalogues that differ only in volatile resource ids, labels or order have the same schema.
- catalogue_
schema_ bytes - Canonical bytes of a schema, for a host to digest into a stable publication revision or a frozen grant schema digest.
- content_
hash - Read a content hash from its canonical resource address.
- content_
resource - Build the canonical resource address for content-addressed bytes.
- current_
step - The undo step open on this thread, if any (see
open_step). - decode_
json - A
Tfrom its JSON bytes, through a JSON value: one byte parser for every action type, compiled here, rather than one per type and crate. - decode_
payload - A
Tfrom the payload of an action of typetype_id, likedecode_json: a group written with what its members share once (crate::group_form) reads as the list of them. - dispatch
- The locus-aware front door, routing
actionper itsExecutionLocus:ClientLocal→apply_localthentransport.replicate;ServerPreferred→transport.submit_to_host, refusing when no authoritative host is reachable. The envelope’s id/timestamp are fixed before submission. - dispatch_
by dispatch, attributing the resulting change toactor— the executor owns the commit boundary, so it’s the only place that chooses which actor a change commits under, rather than each app remembering.- dispatch_
by_ with_ context - Attributed variant of
dispatch_with_context. - dispatch_
with_ context dispatch, carrying semantic provenance into the replicated envelope and the committed CRDT change.- entry_
message - The message
contextis written with byactorondoc: as the continuation of the actor’s previous entry when the change continues its gesture (a head ofdocis the actor’s, of the same gesture and step), else whole. A function of the document, so a replaying device writes the same message, hence the same change. - entry_
of - The entry of the change
hash: its message’s, or for a continuation its gesture’s first entry with the continuation’s action (found by following its writer’s earlier changes). - flatten
- Depth-first flatten of a resource forest into every exported action, parents before children — what the palette lists.
- invoking_
context - The context of the action whose
Action::applyis running on this thread: who invoked it and in which work group (an agent run). Pinned by the envelope like the actor and the time, so a replica replaying the action reads the same value.Noneoutside an apply, or for an action dispatched with no context. - keep_
content_ in - Keep the content every change this thread commits names in
keep(the app’s content store), and read the content a received change names fromread, so recorded actions replay wherever their content reaches. The host sets both once per thread that runs actions. - open_
step - Open the undo step the changes committed on this thread join until the
next one opens: every action applied meanwhile records it as its
gesture, so the document’s history takes them back as one step. The host’s history opens one at every step boundary;Nonecloses it. - place_
schema - The schema of a place inside a resource (
ActionParam::as_place). - replay
- Replay an envelope received from a peer: decode its action via
registryand apply under the envelope’s pinned actor + timestamp. Applied at the envelope’sbase_heads, this reproduces the identical document. - settle_
compensation - Mark the undo (or redo) of the step
hashcomplete: its outside consequence settled. - validate_
json_ schema - Validate one JSON value against the deterministic JSON Schema subset used by Tilo action contracts.
- validate_
surface - validate_
surface_ contracts - Validate every transport-independent invariant. Hosts call this before
publication even when their dynamic widget dispatch cannot enumerate its
effect/view handler table. Tooling that owns an explicit handler table
should use
validate_surfacefor the additional coverage. - verify_
change - Replay the action the change
hashrecords on the document it was authored against, and check that it produces exactly that change: same operations, same actor, time and message, so the same hash. This is what a device that has the app does with every change it receives, beside the relay’s grant check: an author granted an action who wrote something else inside its storage units is caught here.
Type Aliases§
- Args
Builder - Builds an action’s encoded form from arguments already bound against its
declared
params. - Decode
Payload - Decodes one action type’s payload (
ActionRegistry::register_decoder). - Doc
- The CRDT document an action mutates — aliased so call sites read as
“mutate the Doc”; exactly
automerge::AutoCommit. - Interaction
Update - Transport/UI spelling for a semantic interaction lifecycle update.