Live CortexUI Surface

This block renders live CortexUI contract metadata in the docs DOM so AI View can inspect real machine-readable elements instead of only code examples.

AI View can now inspect a live status region, form fields, actions, and table entities on every docs page.
AI-addressable docs entities
ItemState
Search docsReady
Inspect metadataVisible in AI View

Roles Reference

Roles define the semantic type of a UI element within the AI contract. Where data-ai-id identifies which element something is, data-ai-role identifies what kind of thing it is. AI agents use roles to understand what they can do with an element — can they click it? Fill it? Read from it? Navigate through it?

Quick Reference

RoleElement PurposeTypical HTML Elements
actionTriggerable intent — button, link, menu item<button>, <a>, <[role="button"]>
fieldInput that accepts user data<input>, <select>, <textarea>
formContainer that groups fields and an action<form>
tableTabular data display<table>, data grid containers
modalOverlay that requires attention<dialog>, modal wrapper <div>
nav-itemNavigation destination<a>, <button> inside nav
statusRead-only state indicator<span>, <p>, badge elements
screenRoot identity of the current viewOutermost page container
sectionMajor logical region of a screen<section>, <div> groupings
Important

data-ai-role is the single most important attribute in the contract. Without it, no other attribute is interpretable. Every annotated element must have a role.

role="action"

What It Means

An action is an element whose primary purpose is to trigger an operation. Clicking or activating it causes something to happen — a form submits, data saves, a record deletes, a modal opens.

Actions are the verbs of the UI. They carry data-ai-action (the intent name) and data-ai-state (the current condition of that intent).

Which HTML Elements

Use on <button> elements as the default. Can also be used on <a> tags that trigger operations rather than navigating, or on custom elements that have proper keyboard event handling.

<!-- Standard button action -->
<button
  data-ai-role="action"
  data-ai-id="save-profile"
  data-ai-action="save-profile"
  data-ai-state="idle"
>
  Save Profile
</button>

<!-- Anchor used as action (triggers operation, not navigation) -->
<a
  data-ai-role="action"
  data-ai-id="export-csv"
  data-ai-action="export-csv"
  data-ai-state="idle"
  href="#"
  onClick={handleExport}
>
  Export as CSV
</a>

<!-- Destructive action -->
<button
  data-ai-role="action"
  data-ai-id="delete-account"
  data-ai-action="delete-account"
  data-ai-state="idle"
>
  Delete Account
</button>

Common Mistake

Placing role="action" on a <div> without keyboard support. AI agents may attempt to activate actions programmatically. A <div> without tabIndex and a keydown handler will not respond to keyboard-driven activation and will fail accessibility standards simultaneously.

<!-- Wrong: div with no keyboard support -->
<div data-ai-role="action" data-ai-action="save-profile" onClick={save}>
  Save
</div>

<!-- Right: button handles keyboard natively -->
<button data-ai-role="action" data-ai-action="save-profile" onClick={save}>
  Save
</button>

role="field"

What It Means

A field is an element that accepts input from the user. It represents a single named value within a form. Fields carry data-ai-field-type (what kind of data it holds) and data-ai-required (whether it must be filled).

Which HTML Elements

<input>, <select>, <textarea>. Do not use on <label> elements — labels describe fields, they are not fields.

<input
  data-ai-role="field"
  data-ai-id="email-field"
  data-ai-field-type="email"
  data-ai-required="true"
  type="email"
  name="email"
  placeholder="you@example.com"
/>

<select
  data-ai-role="field"
  data-ai-id="role-select"
  data-ai-field-type="select"
  data-ai-required="false"
  name="role"
>
  <option value="admin">Admin</option>
  <option value="viewer">Viewer</option>
</select>

<textarea
  data-ai-role="field"
  data-ai-id="notes-field"
  data-ai-field-type="textarea"
  data-ai-required="false"
  name="notes"
></textarea>

Common Mistake

Using role="field" on a <label>. Labels are not fields — they are descriptions of fields. The AI contract reads fields as elements the agent can write values into. Writing into a label element has no effect.

<!-- Wrong -->
<label data-ai-role="field" data-ai-id="name-label">Name</label>

<!-- Right -->
<label htmlFor="name-input">Name</label>
<input data-ai-role="field" data-ai-id="name-field" data-ai-field-type="text" />

role="form"

What It Means

A form is a container that groups related fields and at least one action (submit). It represents a cohesive unit of data entry. The AI contract can retrieve a form's full field schema via getFormSchema(formId).

Which HTML Elements

The native <form> element is strongly preferred. Custom form-like containers can use a <div> with role="form" in ARIA terms and data-ai-role="form" in the AI contract.

<form
  data-ai-role="form"
  data-ai-id="create-user-form"
  onSubmit={handleSubmit}
>
  <input
    data-ai-role="field"
    data-ai-id="username-field"
    data-ai-field-type="text"
    data-ai-required="true"
    name="username"
  />
  <input
    data-ai-role="field"
    data-ai-id="email-field"
    data-ai-field-type="email"
    data-ai-required="true"
    name="email"
  />
  <button
    data-ai-role="action"
    data-ai-id="create-user-submit"
    data-ai-action="create-user"
    data-ai-state="idle"
    type="submit"
  >
    Create User
  </button>
</form>

Common Mistake

Giving forms generic IDs like form-1 or main-form. Form IDs must be stable and descriptive because agents reference them by ID when calling getFormSchema.

role="table"

What It Means

A table is a container that displays structured, tabular data — rows and columns of records. Tables are read-heavy and often include actions per row (edit, delete, view).

Which HTML Elements

The native <table> element, or a custom data grid wrapper <div> when using a virtualized grid library.

<table
  data-ai-role="table"
  data-ai-id="users-table"
  data-ai-entity="user"
>
  <thead>
    <tr>
      <th>Name</th>
      <th>Email</th>
      <th>Status</th>
      <th>Actions</th>
    </tr>
  </thead>
  <tbody>
    <tr data-ai-entity="user" data-ai-entity-id="user-001">
      <td>Alice Smith</td>
      <td>alice@example.com</td>
      <td><span data-ai-role="status">Active</span></td>
      <td>
        <button
          data-ai-role="action"
          data-ai-id="edit-user-user-001"
          data-ai-action="edit-user"
          data-ai-state="idle"
        >Edit</button>
      </td>
    </tr>
  </tbody>
</table>

role="modal"

What It Means

A modal is an overlay element that takes focus and requires user interaction before returning to the underlying page. Modals typically contain forms or confirmation dialogs.

Which HTML Elements

The native <dialog> element, or a <div> positioned as an overlay with appropriate ARIA attributes.

<dialog
  data-ai-role="modal"
  data-ai-id="confirm-delete-modal"
  data-ai-state="expanded"
  open
>
  <p>Are you sure you want to delete this account?</p>
  <button
    data-ai-role="action"
    data-ai-id="confirm-delete"
    data-ai-action="delete-account"
    data-ai-state="idle"
  >
    Confirm Delete
  </button>
  <button
    data-ai-role="action"
    data-ai-id="cancel-delete"
    data-ai-action="cancel-delete"
    data-ai-state="idle"
  >
    Cancel
  </button>
</dialog>

role="nav-item"

What It Means

A nav-item is a navigation link that moves the user to a different screen or section. Unlike role="action" which triggers operations, role="nav-item" declares navigational intent.

Which HTML Elements

<a> elements inside navigation containers, or <button> elements that trigger client-side routing.

<nav>
  <a
    data-ai-role="nav-item"
    data-ai-id="nav-dashboard"
    href="/dashboard"
  >
    Dashboard
  </a>
  <a
    data-ai-role="nav-item"
    data-ai-id="nav-users"
    href="/users"
  >
    Users
  </a>
  <a
    data-ai-role="nav-item"
    data-ai-id="nav-settings"
    href="/settings"
  >
    Settings
  </a>
</nav>

role="status"

What It Means

A status element displays a read-only state value — a badge showing "Active", a label showing "Pending", a chip showing "Overdue". It is informational, not interactive.

Which HTML Elements

<span>, <p>, badge <div> elements, or any inline element used to display a state.

<span
  data-ai-role="status"
  data-ai-id="order-status"
  data-ai-state="success"
>
  Delivered
</span>

<span
  data-ai-role="status"
  data-ai-id="payment-status"
  data-ai-state="error"
>
  Payment Failed
</span>
Best Practice

Combine data-ai-state with role="status" to give the AI agent a machine-readable state value alongside the human-readable label text. An agent reading a status badge with data-ai-state="error" doesn't need to parse the text "Payment Failed" — it reads the state directly.

role="screen" and role="section"

What They Mean

These roles mark structural containers. screen marks the root of the current view. section marks a major logical region.

In practice, data-ai-screen and data-ai-section on their container elements implicitly carry these roles — you typically don't need to set data-ai-role="screen" separately if data-ai-screen is already present.

<div data-ai-screen="user-profile">

  <section data-ai-section="profile-header">
    <h1>Alice Smith</h1>
    <span data-ai-role="status" data-ai-state="success">Active</span>
  </section>

  <section data-ai-section="profile-form">
    <form data-ai-role="form" data-ai-id="edit-profile-form">
      <!-- fields and actions -->
    </form>
  </section>

</div>