IntentDefining Intents

Defining Intents

Intents are declared under the actions: key in .actions.causet files. Each entry names an intent type your API submits to the runtime.


Full anatomy

actions:
  PURCHASE_TICKET:
    state: ticket             # entity stream this intent operates on
    entity_id_expr: intent.ticket_id
    input:                    # validated before rules run
      ticket_id:  { type: string,  required: true }
      user_id:    { type: string,  required: true }
      show_id:    { type: string,  required: true }
      quantity:   { type: integer, required: true }
 
    preflight:
      rules: [ ... ]
 
    core:
      rules: [ ... ]
 
    side_effects:
      rules: [ ... ]

state

The entity stream (state definition) this intent targets. Must match a declared state: block in your app.

state: user

The runtime loads the entity snapshot for (stream, entity_id) before evaluating rules.


entity_id_expr

Expression that resolves which entity instance to load:

entity_id_expr: intent.user_id

Both intent.<field> and event.<field> compile here. Convention is intent.<field> for command submission.


input

Typed schema for the intent payload. The compiler validates types; the runtime rejects missing required fields before preflight runs.

input:
  user_id:   { type: string,  required: true }
  artist_id: { type: string,  required: true }
  limit:     { type: integer, required: false }

Access input in expressions as intent.user_id, intent.artist_id, etc.

Tip: Avoid naming input fields type — it collides with event.type in expressions.


Rule blocks

Every intent has up to three rule sections:

BlockPurposeAllowed ops
preflightValidation before mutationreject, lookup, if, read-only checks
coreState mutationset, add, sub, push, filter, relationships
side_effectsFan-out after commitemit, submit, schedule, decision

See Rules for phase semantics and Operations for the full op reference.


Minimal example

actions:
  FOLLOW_ARTIST:
    state: user
    entity_id_expr: intent.user_id
    input:
      user_id:   { type: string, required: true }
      artist_id: { type: string, required: true }
 
    preflight:
      rules:
        - name: reject_self_follow
          when: { expr: "intent.user_id == intent.artist_id" }
          then:
            - op: reject
              code: CANNOT_FOLLOW_SELF
              message: "A user cannot follow themselves"
 
    core:
      rules:
        - name: record_follow
          when: {}
          then:
            - op: push
              path: /following
              value: intent.artist_id
 
    side_effects:
      rules:
        - name: emit_followed
          then:
            - op: emit
              event_type: ARTIST_FOLLOWED
              payload:
                user_id:   intent.user_id
                artist_id: intent.artist_id

Next steps

  • Rules — when clauses, cross-stream validation
  • Operations — every op with required fields
  • Examples — end-to-end intent patterns