Skip to content

UX Semantic Layer

Auto-generated from knowledge base TOML files by docs_gen.py. Do not edit manually; run dazzle docs generate to regenerate.

The UX semantic layer expresses WHY interfaces exist and WHAT matters to users, without prescribing HOW to implement it. Personas, scopes, attention signals, and information needs adapt surfaces and workspaces for different roles and contexts.


Persona

A role-based variant that adapts surfaces or workspaces for different user types without code duplication. Controls scope, visibility, and capabilities.

Syntax

as <persona_name>:
  scope: <filter_expression>
  purpose: "<persona-specific purpose>"
  [show: <field1>, <field2>, ...]
  [hide: <field1>, <field2>, ...]
  [show_aggregate: <metric1>, <metric2>, ...]
  [action_primary: <surface_name>]
  [read_only: true|false]

Example

as admin:
  scope: all
  purpose: "Full user management"
  show_aggregate: total_users, active_count
  action_primary: user_create

as manager:
  scope: department = current_user.department
  purpose: "Manage department users"
  hide: salary, ssn
  action_primary: user_invite

as member:
  scope: id = current_user.id
  purpose: "View own profile"
  read_only: true

Best Practices

  • ✅ Use lowercase role names (admin, manager, member)
  • ✅ Base on roles or responsibilities
  • ❌ Avoid device-specific personas (mobile, desktop)
  • ❌ Avoid preference-based personas (dark-mode-user)

Related: Ux Block, Scope, Workspace


Purpose

A single-line statement capturing the semantic intent of a surface or workspace - explaining WHY it exists.

Syntax

purpose: "<single line explanation>"

Example

purpose: "Track customer support ticket resolution"

Best Practices

  • ✅ Focus on user intent, not implementation
  • ✅ Answer 'why does this exist?'
  • ✅ Keep to one line
  • ❌ Avoid 'List of...' or 'CRUD for...'

Related: Ux Block


Attention Signals

Data-driven conditions that require user awareness or action. Signals have severity levels and can trigger actions.

Syntax

attention <critical|warning|notice|info>:
  when: <condition_expression>
  message: "<user-facing message>"
  [action: <surface_name>]

Example

surface task_list "Tasks":
  uses entity Task
  mode: list

  section main:
    field title
    field status

  ux:
    purpose: "Track tasks and surface overdue work"

    attention critical:
      when: due_date < today and status != done
      message: "Overdue task"
      action: task_edit

    attention warning:
      when: priority = high and status = todo
      message: "High priority - needs assignment"
      action: task_assign

Best Practices

  • ✅ Use for data anomalies requiring action
  • ✅ Use for time-sensitive conditions
  • ❌ Don't use for purely visual styling
  • ❌ Don't overuse - reserve for truly important conditions

Related: Ux Block, Conditions


Scope

Row filter defining what data a persona can see or write. Two layers: (1) the entity-level scope: block — the canonical RBAC row filter, paired with permit: (ADR-0010) — and (2) a display-layer scope: inside a surface ux 'as :' variant. Filters are 'all' or a comparison expression; each entity-level rule binds to personas via an 'as:' clause.

Syntax

# Entity-level (canonical RBAC — every entity needs permit: AND scope:)
scope:
  <create|read|update|delete|list>: all | <expr> | via Junction(<bindings>) | not via Junction(<bindings>)
    as: <persona>(, <persona>)* | *

# Filter expression forms
<field> = current_user
<field> = current_user.<attribute>
<fk_path>.<field> = current_user.<attribute>
<field> = <value>
<expr1> and <expr2>
<expr1> or <expr2>
not (<expr>)

# Surface ux variant (display-layer narrowing)
ux:
  as <persona>:
    scope: all | <expr>

Example

# Entity-level scope: block — pairs with permit:
entity Ticket "Support Ticket":
  id: uuid pk
  created_by: ref User required
  assigned_to: ref User

  permit:
    list: role(customer) or role(agent)
    read: role(customer) or role(agent)
    update: role(agent)

  scope:
    list: created_by = current_user
      as: customer
    list: all
      as: agent
    read: created_by = current_user
      as: customer
    read: all
      as: agent
    update: assigned_to = current_user
      as: agent

# Surface ux variant — display-layer scope
surface ticket_list "Tickets":
  uses entity Ticket
  mode: list
  ux:
    as agent:
      scope: status = open and assigned_to = current_user

Related: Persona, Conditions, Scope Runtime


Information Needs

Specifications for how data should be displayed, sorted, filtered, and searched - the 'what' without the 'how'. On list surfaces these directives control the DataTable's interactive features.

Syntax

show: field1, field2, field3
sort: field1 desc, field2 asc
filter: status, category, assigned_to
search: title, description, tags
empty: "No items found. Create your first item."

Related: Ux Block, Datatable


Defaults

Default field values for a persona in create/edit forms. Pre-populates fields based on the user's role or context.

Syntax

ux:
  as <persona_name>:
    defaults:
      <field>: <identifier-value>   # e.g. an enum value like draft
      <field>: "<literal string>"
      <field>: current_user

Example

surface ticket_create "New Ticket":
  uses entity Ticket
  mode: create

  section main:
    field title
    field description
    field priority

  ux:
    purpose: "Create new support ticket"

    as customer:
      defaults:
        created_by: current_user
        status: open
        priority: medium

    as agent:
      defaults:
        created_by: current_user
        status: open
        assigned_to: current_user

surface order_create "New Order":
  uses entity Order
  mode: create

  ux:
    as sales_rep:
      defaults:
        created_by: current_user
        status: draft
        region: "eu-west"

Related: Persona, Ux Block, Surface


Ux Block

Optional metadata on surfaces and workspaces expressing WHY they exist and WHAT matters to users, without prescribing HOW to implement it.

Syntax

ux:
  purpose: "<semantic intent>"

  [show: <field1>, <field2>, ...]
  [sort: <field> [asc|desc], ...]
  [filter: <field1>, <field2>, ...]
  [search: <field1>, <field2>, ...]
  [empty: "<message>"]

  [attention <level>:]
    when: <condition>
    message: "<user message>"
    [action: <surface_name>]

  [as <persona>:]
    [scope: <filter_expression>]
    [purpose: "<persona purpose>"]
    [show: <fields>]
    [hide: <fields>]
    [show_aggregate: <metrics>]
    [action_primary: <surface>]
    [read_only: true|false]

Example

surface user_list "Users":
  uses entity User
  mode: list

  section main:
    field name
    field email

  ux:
    purpose: "Manage user accounts"

    sort: name asc
    filter: role, is_active
    search: name, email

    attention warning:
      when: is_active = false
      message: "Inactive account"

    as admin:
      scope: all
      action_primary: user_create

    as member:
      scope: id = current_user.id
      read_only: true

Related: Purpose, Information Needs, Attention Signals, Persona, Datatable