IntentConcept

Intents — Concept

An intent is a declared command — the contract between your API and the Causet runtime. When a client submits an intent, the runtime loads the target entity’s current state, runs your rules in order, appends events to the ledger, and returns success or a structured rejection.

Intents replace ad-hoc service logic with declarative, replayable rules.


Why intents exist

Most application bugs come from scattered validation and state mutation spread across controllers, services, and background jobs. Causet centralizes the write path:

  1. Validate input before any mutation (preflight)
  2. Mutate entity state deterministically (core)
  3. Emit domain events and schedule follow-up work (side_effects)

Every successful intent produces an append-only record in the ledger. You can replay history and get the same state every time.


Intents vs events vs projections

LayerRoleWhen it runs
IntentAccept a command, run rules, write ledgerSynchronous — write path
EventImmutable fact emitted by an intentWritten to ledger, published async
ProjectionMaterialized read table from eventsAsync — read path

Intents emit events. Projections consume events. Queries read projections. Never skip the chain: intent → event → projection → query.


Deterministic rules

Rules inside an intent must be pure relative to the ledger:

  • No HTTP calls, database lookups outside LOOKUP_FIELD, or external I/O
  • No now(), random(), or uuid() — use event.ts and deterministic IDs
  • Same entity state + same input → same mutations and same emitted events

This is what makes replay, audit, and debugging possible.


Rule phases (mental model)

  • Preflight — read-only validation. Only reject (and read ops like lookup) allowed.
  • Core — mutate the target entity. set, add, push, relationships. No emit.
  • Side effects — fan-out after commit. emit, submit, schedule, decision. No direct state writes.

If preflight rejects, nothing is written. If core succeeds, the ledger is committed before side effects run.


Where intents are declared

# app.causet
includes:
  actions: [./actions/**/*.actions.causet]

Each .actions.causet file declares intents under the actions: key. The compiler transpiles them into the internal ruleset the runtime executes.


Next steps

  • Overview — guide map for this section
  • Defining Intents — input schema, entity routing, full anatomy
  • Rules — preflight, core, and side_effects in depth
  • Examples — concert-app patterns