Skip to main content

Your First Annotated Action

This guide walks you through annotating a single button with AXAG semantics in under five minutes.

Scenario​

You have a product search button on an e-commerce page. Currently, it looks like this:

Before — unannotated search
<div class="search-container">
<input type="text" id="searchInput" placeholder="Search products..." />
<button class="btn-search" onclick="searchProducts()">
Search
</button>
</div>

An agent looking at this HTML cannot determine:

  • What entity is being searched
  • What parameters are required vs optional
  • Whether this operation has side effects
  • What scope the search operates within

Step 1: Identify the Semantic Dimensions​

Before annotating, answer these questions:

QuestionAnswer
What is the intent?Search for products
What entity does this operate on?Product
What type of action is this?Read (non-mutating)
What parameters are required?query
What parameters are optional?category, price_min, price_max
What scope does this operate in?Public — no sign-in needed
What is the risk level?None
Is it idempotent?Yes

Step 2: Add AXAG Annotations​

🔬 Proposed Implementation Pattern

The attribute syntax shown below is a Proposed Implementation Pattern.

After — fully annotated product search
<div class="search-container">
<input
type="text"
id="searchInput"
placeholder="Search products..."
axag-parameter="query"
axag-parameter-type="string"
axag-parameter-required="true"
axag-parameter-description="Free-text search query for product name, description, or SKU"
/>
<button
axag-intent="product.search"
axag-entity="product"
axag-action-type="read"
axag-required-parameters='["query"]'
axag-optional-parameters='["category","price_min","price_max"]'
axag-scope="public"
axag-risk-level="none"
axag-idempotent="true"
axag-description="Search the product catalog by text query with optional filters"
class="btn-search"
onclick="searchProducts()"
>
Search
</button>
</div>

The same annotation as a macro​

The identity, safety and parameter-name attributes fit in one axag macro; the description stays longhand:

After — macro shorthand
<button
axag="read:product.search!none?idempotent&scope=public&req=query&opt=category,price_min,price_max"
axag-description="Search the product catalog by text query with optional filters"
class="btn-search"
onclick="searchProducts()"
>
Search
</button>

Both forms produce the same Semantic Manifest. npx @web-axag/cli fmt converts between them.

Step 3: Validate Your Annotation​

Check your annotation against these rules:

  • ✅ axag-intent uses entity.verb format
  • ✅ axag-entity identifies the domain object
  • ✅ axag-action-type is one of: read, write, delete, navigate
  • ✅ Required parameters are listed
  • ✅ Risk level is appropriate for the action type
  • ✅ Idempotency is declared for read operations

Step 4: Verify the Semantic Contract​

The annotation now declares a contract:

"This button performs a product search (a read operation on the product entity) that requires a query parameter, optionally accepts category, price_min, and price_max, is public, has no risk, and is idempotent."

An agent reading this contract can:

  1. Discover the operation without parsing the DOM
  2. Construct valid parameters without guessing
  3. Assess safety without inspecting visual indicators
  4. Retry safely because idempotency is declared

Common Mistakes​

MistakeProblemFix
Missing axag-intentAgent cannot determine purposeAlways declare intent
Using axag-action-type="write" for a searchMisclassifies a read operationUse read for non-mutating operations
Omitting axag-scopeAgent cannot determine access boundariesAlways declare scope
Setting axag-risk-level="high" for a searchOver-classifying a safe operationMatch risk to actual impact

Next Steps​