Actors

An actor is a persona — the "who" a flow is walked by. Before you can describe a business process or a journey, you name the actors that travel them. An actor is a first-class, project-global node: declared once, referenced everywhere by name.

sub-domains/platform/_precise/systems.vishwakarma
actor Customer {
  axis "user_id != ''"
  doc  "A signed-in Chowk shopper who browses, places, pays for, and tracks orders."
}

The axis predicate is what makes an actor more than a label: it is a boolean expression over the caller's identity that decides which real callers are this persona. Customer is any caller with a non-empty user_id — a signed-in shopper. The internal automation principal is the inverse:

sub-domains/platform/_precise/systems.vishwakarma
actor System {
  axis "user_id == ''"
  doc  "Internal automation / system principal — subscription- and saga-driven calls with no human user."
}

Because the predicate is real, the compiler can check a flow's reachability: if a business process routes an actor into a step whose authorization that actor's predicate can never satisfy, it tells you the flow routes the persona into a wall (see Reconciliation).

Actors are project-global

An actor name is unique across the whole project, so by convention every persona is declared once — in Chowk, in the platform sub-domain — and reused by FQN (platform.v1.Customer). A flow in the same sub-domain may use the bare name; one in another sub-domain uses the full FQN. Centralizing them keeps one authoritative persona vocabulary the whole overlay shares.

Where an actor attaches

  • A business_process names its primary actor at the top (actor platform.v1.Customer).
  • A single step can override it with by <Actor> — a swimlane handoff to a different persona for that step (an operator packing an order inside an otherwise system-run flow). A change of actor between consecutive steps is a handoff, drawn as a swimlane boundary.
  • A journey names the actor whose arc it traces.

Actors read caller axes

The identity attributes an actor's predicate reads come from the caller. The framework provides a floor (kind, user_id, originating_caller); your app declares any additional axes it authenticates with in a project-global caller_axes block:

sub-domains/enterprise_kernel/caller_axes.vishwakarma
caller_axes {
  axis tenant_id  uuid   "Tenant scope the caller is operating in. Empty for single-tenant or system callers."
  axis session_id string "Opaque session identifier (surrogate key of the verified session)."
  axis client_id  string "Stable client/device fingerprint."
  axis role       string "The caller's coarse role (CUSTOMER | OPERATOR). Empty for anonymous callers."
}

An actor predicate — and the policies and guards elsewhere in the model — may reference any declared axis; a reference to an undeclared one fails to compile.