LearnYour First Intent

Your First Intent (Action)

Continuing the concert app: intents are commands your app submits. Rules run in three phases:

preflight → core → side_effects

In the DSL, intents are declared under the actions: key in .actions.causet files.

Project: Follow along in the Concert app from causet init. Open actions/.

Prerequisite: Your First EventARTIST_FOLLOWED, SHOW_ANNOUNCED.


Follow an artist

# actions/follow.actions.causet
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
 
    core:
      rules:
        - name: increment_following
          when: {}
          then:
            - op: add
              path: /following_count
              value: 1
 
    side_effects:
      rules:
        - name: emit_followed
          then:
            - op: emit
              event_type: ARTIST_FOLLOWED
              payload:
                user_id:   intent.user_id
                artist_id: intent.artist_id
PhaseThis intent
PreflightReject self-follow
CoreIncrement following_count on the user
Side effectsEmit ARTIST_FOLLOWED

Announce a show

# actions/show.actions.causet
actions:
  ANNOUNCE_SHOW:
    state: artist
    entity_id_expr: intent.artist_id
    input:
      artist_id: { type: string, required: true }
      show_id:   { type: string, required: true }
      venue:     { type: string, required: true }
      date:      { type: string, required: true }
      title:     { type: string, required: true }
 
    core:
      rules:
        - name: emit_announced
          when: {}
          then:
            - op: emit
              event_type: SHOW_ANNOUNCED
              payload:
                artist_id: intent.artist_id
                show_id:   intent.show_id
                venue:     intent.venue
                date:      intent.date
                title:     intent.title

Submit via CLI

Follow Pearl Jam:

causet intent FOLLOW_ARTIST \
  --fork main \
  --stream user_stream \
  --entity user-1 \
  --payload '{"user_id":"user-1","artist_id":"artist-pearl-jam"}'

Announce a show:

causet intent ANNOUNCE_SHOW \
  --fork main \
  --stream artist_stream \
  --entity artist-pearl-jam \
  --payload '{"artist_id":"artist-pearl-jam","show_id":"show-pj-brooklyn-2026","venue":"Barclays Center","date":"2026-09-15","title":"Pearl Jam - Dark Matter Tour"}'

A reject in preflight aborts the intent — no state changes, no events.


Rule phases reference

PhaseAllowedForbidden
Preflightreject, lookup, read-only checksmutations, emit, submit
Coreset, add, emit, relationship_createreject, submit, decision
Side effectsemit, submit, schedule, decisiondirect state writes

Full reference: Intent Rules.


Concert app so far

concert-app/
  app.causet
  states/     user.state.causet, artist.state.causet
  events/     follow.events.causet, show.events.causet
  actions/    follow.actions.causet, show.actions.causet

Next steps