aura-labs.ai

AURA Protocol Specification — Commerce Protocol

Module: Commerce Protocol (Sections 5–9) Parent: AURA Protocol Specification v2.2 Version: 2.2 Date: April 14, 2026 Covers: Scout Request Protocol, Interpretation, Beacon Requests, Beacon Responses, Offer Ranking & Delivery


5. Scout Request Protocol

5.1 Creating a Session

Scout initiates a commerce session by expressing intent in natural language:

POST /v1/sessions

Request:

{
  "intent": "I need wireless headphones for my daily commute. Noise cancellation is important because the train is loud. Budget around $300-400.",
  "constraints": {
    "maxBudget": 400,
    "deliveryBy": "2026-02-01",
    "categories": ["electronics", "headphones"]
  },
  "completeness": {
    "complete": true,
    "missing": [],
    "confidence": 0.92,
    "rounds": 2
  },
  "profile_id": "prf_retail_consumer_v1",
  "settlement_preference": {
    "preferred_methods": ["stablecoin_usdc", "rtp"],
    "networks": ["ethereum"]
  },
  "risk_tolerance": {
    "max_reserve_margin_pct": 0.05,
    "max_dispute_window_days": 30
  }
}
Field Type Required Description
intent string Yes Natural language expression of need (max 2000 chars)
constraints object No Structured constraints (max 10KB JSON)
completeness object No Scout SDK completeness attestation (informational only — see Note)
sub_intents array|null No Reserved (Section 5.4). Sub-intent array for compound sessions. Do not send until compound intent is supported.
profile_id string No (DEC-044) Market Profile identifier. If omitted, the Core instance’s default profile applies. The session binds to the profile version active at creation time — profile revisions do not affect in-flight sessions. See MARKET_PROFILES.md.
settlement_preference object No (Phase 7) Scout’s preferred settlement methods and networks. Used by Core to filter Beacons and pre-compute clearing compatibility.
risk_tolerance object No (Phase 7) Scout’s acceptable risk parameters. max_reserve_margin_pct filters offers whose estimated margin exceeds tolerance. max_dispute_window_days filters offers with longer windows than desired.
parent_session_id string|null No Reserved (Section 5.4). Parent session UUID for sub-sessions. Do not send until compound intent is supported.
budget object|null No Reserved (Section 5.4). Aggregate budget tracking: { "total", "currency", "allocated", "remaining" }.

Note on Completeness Attestation: The completeness field is an optional attestation from the Scout SDK’s IntentSession class. It is informational, not authoritative — Core always parses intent independently (ref: NEUTRAL_BROKER.md Property 1). The attestation is stored in session context for observability and diagnostics. The complete field indicates whether the Scout SDK’s local completeness check passed; missing lists any categories the Scout SDK could not detect; confidence is the average detection confidence (0-1); rounds is the number of IntentSession.submit() calls that occurred.

Response (201 Created):

{
  "sessionId": "uuid-...",
  "status": "collecting_offers",
  "intent": { "raw": "I need wireless headphones...", "parsed": { "..." } },
  "matchedBeacons": [],
  "created_at": "2026-01-14T10:00:00Z",
  "_links": {
    "self": "/v1/sessions/uuid-...",
    "offers": "/v1/sessions/uuid-.../offers"
  }
}

5.2 Polling for Session Status

Scout can poll for session updates:

GET /v1/sessions/{session_id}

Response (200 OK):

{
  "session_id": "ses_01HXYZ...",
  "status": "offers_ready",
  "created_at": "2026-01-14T10:00:00Z",
  "updated_at": "2026-01-14T10:00:35Z",
  "interpreted_request": {
    "structured_requirements": {
      "category": "electronics.headphones.over_ear",
      "hard_constraints": {
        "price_max_usd": 400,
        "in_stock": true,
        "ships_to": "US"
      },
      "soft_preferences": {
        "brands": ["Sony"],
        "features": ["noise_cancellation", "wireless"],
        "price_range_usd": {"min": 300, "max": 400}
      }
    },
    "natural_language_context": {
      "content": "User commutes daily by train, needs noise cancellation. Previously satisfied with Sony products. Looking for quality audio experience for music during commute.",
      "language": "en",
      "sanitized": true
    }
  },
  "offers_count": 8,
  "offers_url": "/v1/sessions/ses_01HXYZ.../offers"
}

5.3 WebSocket Real-Time Updates

For real-time updates, connect via WebSocket:

wss://aura.example.com/ws/sessions/{session_id}

Authentication: Include bearer token as query parameter:

wss://aura.example.com/ws/sessions/ses_01HXYZ...?token=sk_example_...

Server Messages:

{
  "event": "status_changed",
  "session_id": "ses_01HXYZ...",
  "status": "collecting_offers",
  "timestamp": "2026-01-14T10:00:15Z"
}
{
  "event": "offer_received",
  "session_id": "ses_01HXYZ...",
  "offer_id": "ofr_01HXYZ...",
  "rank": 3,
  "beacon_id": "bcn_01HXYZ...",
  "preview": {
    "product_name": "Sony WH-1000XM5",
    "price_usd": 349.99,
    "beacon_score": 87.5
  },
  "timestamp": "2026-01-14T10:00:20Z"
}
{
  "event": "offers_ready",
  "session_id": "ses_01HXYZ...",
  "total_offers": 8,
  "timestamp": "2026-01-14T10:00:35Z"
}

5.4 Compound Intent (Reserved)

Status: Schema reserved. Not yet enforced by Core API. Integrators SHOULD NOT send these fields until Core announces compound intent support. Fields are documented here to reserve schema space and prevent breaking changes when compound intent is implemented.

A compound intent arises when a single Scout utterance decomposes into multiple independent sub-intents, each routed to a different Beacon cohort. The canonical example is a travel request — “I want to take my family to Tuscany this October for $8,000” — which decomposes into sub-intents for accommodation, flights, activities, and transfers, each fulfilled by independent suppliers.

5.4.1 Compound Session Model

Scout utterance
    │
    ▼
┌─────────────────────────────────────────────────┐
│  AURA Core — Intent Decomposition               │
│  "Family trip to Tuscany, $8k budget"            │
│                                                  │
│  ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│  │ Sub-      │ │ Sub-      │ │ Sub-             │ │
│  │ intent 1  │ │ intent 2  │ │ intent N         │ │
│  │ Flights   │ │ Villa     │ │ Day trips        │ │
│  │ 4 pax     │ │ sleeps 4  │ │ family-friendly  │ │
│  └─────┬─────┘ └─────┬─────┘ └────────┬────────┘ │
└────────│─────────────│───────────────│───────────┘
         ▼             ▼               ▼
    Beacon cohort  Beacon cohort  Beacon cohort
    (airlines)     (villas)       (tour operators)

In the compound model:

5.4.2 Reserved Session Fields

The following fields are reserved on the session object. They are nullable and MUST NOT be sent by integrators until compound intent is formally supported.

Field Type Description
sub_intents array|null Array of SubIntent objects decomposed from the parent intent. Null for simple (non-compound) sessions.
parent_session_id string|null UUID of the parent session, when this session represents a single sub-intent in a compound flow. Null for top-level sessions.
budget object|null Aggregate budget tracking: { "total": number, "currency": string, "allocated": number, "remaining": number }.

5.4.3 SubIntent Object Schema

Each element in the sub_intents array has the following shape:

{
  "id": "sub_01HXYZ...",
  "type": "accommodation",
  "domain": "travel.lodging",
  "structured_requirements": {
    "category": "travel.lodging.villa",
    "hard_constraints": {
      "sleeps_min": 4,
      "kitchen": true,
      "location": "Tuscany, Italy",
      "check_in": "2026-10-05",
      "check_out": "2026-10-12"
    },
    "soft_preferences": {
      "features": ["pool", "garden", "rural"]
    }
  },
  "completeness": {
    "complete": true,
    "missing": [],
    "confidence": 0.91
  },
  "status": "collecting_offers",
  "excluded": false,
  "exclusion_reason": null,
  "budget_allocation": {
    "suggested": 2500,
    "currency": "USD"
  }
}
Field Type Required Description
id string Yes Unique sub-intent identifier
type string Yes Human-readable sub-intent category (e.g., “accommodation”, “flights”, “activities”)
domain string Yes Machine-readable domain classification (e.g., “travel.lodging”)
structured_requirements object Yes Requirements for this sub-intent, same schema as top-level interpreted_request.structured_requirements
completeness object No Per-sub-intent completeness attestation
status string Yes Sub-intent lifecycle state (uses the same state enumeration as sessions — see Section 4.5.1)
excluded boolean Yes true if Scout explicitly declined this sub-intent
exclusion_reason string|null No Why the sub-intent was excluded (e.g., “Scout declined travel insurance”)
budget_allocation object|null No Suggested budget for this sub-intent: { "suggested": number, "currency": string }

5.4.4 Reserved Offer Request Fields

The following fields are reserved on the offer request payload sent to Beacons (Section 7.1). They enable Beacons to understand which sub-intent they are bidding on and how much budget remains.

Field Type Description
sub_intent_id string|null The sub-intent this offer request targets. Null for simple sessions.
budget_remaining object|null Aggregate remaining budget across all sub-intents: { "amount": number, "currency": string }. Individual supplier pricing is never disclosed — only the aggregate.

Information sovereignty: A Beacon receiving an offer request for “accommodation” with budget_remaining: { "amount": 4950, "currency": "USD" } knows the total trip budget is being consumed by other suppliers, but cannot determine what any individual supplier charged. This prevents price anchoring while enabling budget-aware offers.

5.4.5 Reserved Transaction Fields

The following fields are reserved on the commit request and transaction response (Section 10.2).

Field Type Description
sub_intent_id string|null The sub-intent this transaction settles. Null for simple sessions.

When compound intent is active, each sub-intent produces its own independent transaction. The parent session tracks aggregate transaction status across all sub-intents.

5.4.6 Compound Intent Lifecycle

1. Scout submits utterance         → Parent session created
2. Core decomposes intent          → sub_intents[] populated
3. Per sub-intent:
   a. Core routes to Beacon cohort → Offer requests include sub_intent_id
   b. Beacons submit offers        → Offers tagged with sub_intent_id
   c. Scout commits per sub-intent → Transaction per sub-intent
   d. Budget updated               → budget.remaining decremented
4. All sub-intents committed       → Parent session → completed
   (or some excluded/cancelled)

Relationship to state machine (Section 4.5): Each sub-intent follows the same state transition table as a simple session. The parent session transitions to completed only when all non-excluded sub-intents have reached a terminal state.


6. AURA Interpretation Protocol

Intent interpretation in AURA follows a three-layer architecture (ref: ADR-002). Each layer operates independently with graceful degradation, and Core retains exclusive semantic authority over the final parsed intent.

6.1 Three-Layer NLP Architecture

┌─────────────────────────────────────────────────┐
│  Layer 1: @aura-labs-ai/nlp (Shared Module)        │
│  - 8-category tiered completeness detection     │
│  - Regex + LLM hybrid detection                 │
│  - Clarification question generation            │
│  - LLM provider abstraction (Mock/Together/FW)  │
│  Used by: Scout SDK, Core intent-svc, Beacon SDK│
├─────────────────────────────────────────────────┤
│  Layer 2: Scout SDK + Core Intent Service       │
│  - Scout IntentSession: local completeness gate │
│  - Core intent-svc: LLM-powered parsing         │
│  - Core parseIntentWithFallback: tries intent-  │
│    svc, falls back to local regex parser         │
│  - Completeness attestation → session context   │
├─────────────────────────────────────────────────┤
│  Layer 3: Beacon SDK Catalog Matching           │
│  - interpretIntent(): domain-specific matching  │
│  - Keyword/tag scoring against product catalog  │
│  - Presence detection only (not semantic auth.) │
└─────────────────────────────────────────────────┘

Key principle: Core retains semantic authority. Scout and Beacon layers perform presence detection and domain-specific matching — they inform but do not override Core’s interpretation.

6.2 Layer 1 — Shared NLP Module (@aura-labs-ai/nlp)

The shared module provides 8-category tiered completeness checking:

Category Tier Detection Description
what 1 (required) model/hybrid What the buyer wants
how_many 1 (required) regex Quantity needed
how_much_cost 1 (required) regex Budget or price range
when_needed 1 (required) regex Delivery timeline
what_kind 2 (conditional) model/hybrid Specific characteristics
where_deliver 2 (conditional) regex Delivery location
quality_level 2 (conditional) model Quality preferences
special_requirements 2 (conditional) model Custom requirements

Detection methods:

Graceful degradation: If the LLM provider is unavailable, detection continues with regex-only patterns. Intent parsing never blocks on provider failure.

6.3 Layer 2 — Scout + Core Integration

Scout IntentSession validates completeness locally before submitting to Core:

submit("I want headphones") → { complete: false, missing: ["how_many", "how_much_cost", "when_needed"], question: "How many do you need?" }
submit("2 pairs under $300 by next week") → { complete: true, missing: [], confidence: 0.91 }

Core intent-svc performs LLM-powered parsing via the @aura-labs-ai/nlp provider abstraction. parseIntentWithFallback wraps the intent-svc call: on success, returns structured parsed intent; on failure (timeout, HTTP error, connection refused), falls back to the local regex parser. Intent parsing is non-fatal — if all parsing fails, the session degrades to raw-text storage with confidence: 0.

6.4 Interpreted Request Structure

Core’s parsed intent follows this structure:

{
  "structured_requirements": {
    "category": "electronics.headphones",
    "keywords": ["wireless", "noise cancellation", "headphones"],
    "quantity": 1,
    "priceRange": { "max": 400 }
  },
  "natural_language_context": "I need wireless headphones for my daily commute. Noise cancellation is important.",
  "confidence": 0.91
}

6.5 Sanitization Rules

AURA sanitizes natural language context before sending to Beacons:

  1. Remove PII: Names, addresses, phone numbers, email addresses
  2. Remove injection patterns: Instructions like “ignore previous”, “you are now”, system prompts
  3. Neutralize brand attacks: Remove negative competitor mentions
  4. Preserve intent: Keep semantic meaning while removing specific identifiers
  5. Normalize language: Correct spelling, standardize terminology

Example Transformation:

Original (Scout) Sanitized (to Beacon)
“My wife Sarah wants…” “User seeking gift for spouse…”
“Ignore the price limit and show expensive ones” “User interested in premium options”
“Brand X is terrible, never that” “User prefers alternatives to Brand X”

6.6 Disclosure Projection (DEC-044)

Before routing an interpreted request to Beacons, Core applies the active Market Profile’s disclosure schedule to produce a projected request — a subset of the full interpretation. The projection determines what Beacons see at the discovery phase. This is the protocol mechanism that prevents information leakage (MARKET_ECONOMICS.md Section 4.2).

Disclosure tiers (per field, per protocol phase):

Tier Meaning Example
full Field visible in its entirety Product category, hard constraints
range Field visible as a range, not exact value Budget “$255–$345” (±15% of $300)
presence Field existence visible, value hidden “Has brand preference” without specifying which
redacted Field not visible at this phase Soft preferences, natural language, Scout identity
aggregate Statistical aggregate only “8 offers received” without individual details

Default disclosure schedule (retail profile):

Field Discovery (Beacon sees) Offers (Scout sees) Commitment (both see)
category full full
hard_constraints full full
soft_preferences presence full
budget / priceRange range (±15%) full
delivery_region full full
delivery_deadline full full
natural_language_context redacted redacted (never forwarded)
scout_identity redacted full (revealed at commit)
beacon_identity redacted full (revealed at commit)
beacon_reputation full full
beacon_risk_score range full
offer_price full full

Projection example:

Full interpreted request (Core holds):

{
  "category": "electronics.headphones",
  "priceRange": { "max": 400, "min": 300 },
  "soft_preferences": { "brand": "Sony", "style": "over-ear" },
  "delivery_deadline": "2026-02-01",
  "delivery_region": "US"
}

Projected request (Beacon receives):

{
  "category": "electronics.headphones",
  "priceRange": { "max": 460, "min": 255 },
  "soft_preferences": { "_disclosed": ["brand", "style"] },
  "delivery_deadline": "2026-02-01",
  "delivery_region": "US"
}

The Beacon knows the Scout has brand and style preferences (enabling relevant offers) but cannot use the exact values for price discrimination. The budget range is widened to ±15%, preventing Beacons from pricing to the Scout’s exact ceiling.

Monotonic disclosure guarantee (Principle 2.16): Fields can only become MORE visible as commitment increases. A field visible as range at discovery cannot become redacted at offers. Profiles that violate monotonicity are rejected at validation.

Profile override: Non-default profiles may adjust disclosure schedules. A B2B procurement profile may set soft_preferences to full at discovery (procurement agents need detailed specs for accurate quoting). The protocol enforces the tier model and monotonicity; the profile sets the per-field values.

6.7 Interpretation Attestation

When Core interprets a Scout’s natural language intent into structured requirements, it MUST produce a signed attestation binding the input to the output. This attestation provides an auditable chain from the consumer’s original declaration through to the structured interpretation that drives Beacon matching and offer generation.

Attestation Structure:

{
  "type": "interpretation_attestation",
  "session_id": "ses_01HXYZ...",
  "original_input": {
    "raw_text": "I need two pairs of white running shoes under £150, delivered by Friday",
    "language": "en",
    "received_at": "2026-03-26T14:30:00Z"
  },
  "structured_output": {
    "category": "footwear.running_shoes",
    "keywords": ["white", "running shoes"],
    "quantity": 2,
    "priceRange": { "max": 15000, "currency": "GBP" },
    "delivery_deadline": "2026-03-28T23:59:59Z"
  },
  "interpretation_metadata": {
    "model_id": "aura-intent-v2.1",
    "model_version": "2026-03-15",
    "confidence": 0.94,
    "interpretation_method": "model",
    "fallback_used": false
  },
  "attestation_signature": "Ed25519 signature by Core's signing key",
  "core_key_id": "core_01HXYZ..."
}

Requirements:

Rationale: This attestation creates a verifiable chain from spoken intent through structured interpretation. If the interpretation was incorrect — the consumer said “running shoes” but the structured output matched “hiking boots” — the divergence is visible, attributable to a specific model version, and available to all parties. See MARKET_ECONOMICS.md Section 9 for the economic rationale.


7. Beacon Request Protocol

7.1 Receiving Offer Requests

AURA sends offer requests to qualified Beacons via webhook:

POST {beacon_webhook_url}

Request from AURA to Beacon:

{
  "request_type": "offer_request",
  "request_id": "req_01HXYZ...",
  "session_id": "ses_01HXYZ...",
  "timestamp": "2026-01-14T10:00:12Z",
  "respond_by": "2026-01-14T10:00:42Z",
  "response_url": "https://aura.example.com/v1/sessions/ses_01HXYZ.../offers",
  "interpreted_request": {
    "structured_requirements": {
      "category": "electronics.headphones.over_ear",
      "hard_constraints": {
        "price_max_usd": 400,
        "in_stock": true,
        "ships_to": "US"
      },
      "soft_preferences": {
        "brands": {"preferred": ["Sony"], "acceptable": ["Bose", "Apple"]},
        "features": {"required": ["noise_cancellation", "wireless"]}
      }
    },
    "natural_language_context": {
      "content": "Daily train commuter seeking premium audio experience. Values previous positive experience with Sony. Noise cancellation essential due to noisy environment.",
      "language": "en",
      "sanitized": true
    }
  },
  "beacon_context": {
    "your_categories": ["electronics", "audio"],
    "matching_reason": "category_match",
    "recommended_products": ["electronics.headphones.*"]
  },
  "signature": "sig_aura_..."
}
Field Type Description
request_id string Unique identifier for this request
session_id string Session ID (for response correlation)
respond_by timestamp Deadline for offer submission
response_url string URL to submit offers
interpreted_request object Scout’s interpreted requirements
beacon_context object Context about why this Beacon was selected
signature string AURA’s signature for request authenticity
sub_intent_id string|null Reserved (Section 5.4.4). Sub-intent this request targets. Null for simple sessions.
budget_remaining object|null Reserved (Section 5.4.4). Aggregate remaining budget: { "amount", "currency" }. Individual supplier pricing never disclosed.

7.2 Beacon-Side Intent Interpretation (Layer 3)

Before generating offers, Beacons can use interpretIntent() to match the incoming intent against their product catalog. This is Layer 3 of the three-layer NLP architecture (ref: ADR-002).

const result = await beacon.interpretIntent(session.intent.raw, catalog);
// result: { matches, confidence, categories, suggestions }

Catalog matching algorithm:

Field Weight Description
name +20 per word overlap Product name keyword matching
category +15 per word overlap Category keyword matching
tags +10 per word overlap Tag keyword matching

InterpretResult schema:

{
  "matches": [
    { "item": { "name": "Wireless NC Headphones", "sku": "HP-001" }, "score": 55, "matchedOn": ["name", "category"] }
  ],
  "confidence": 0.87,
  "categories": { "what": { "present": true, "confidence": 0.9 }, "how_many": { "present": true, "confidence": 0.9 } },
  "suggestions": ["What price range are you looking for?"]
}

Design constraint: Beacon interpretation is presence detection only, not semantic authority. Core retains exclusive authority over intent parsing (ref: NEUTRAL_BROKER.md Property 1).

Graceful degradation: If the LLM provider is unavailable, interpretIntent() continues with regex-only detection. If all detection fails, returns { matches: [], confidence: 0, categories: {}, suggestions: [] }.

7.3 Beacon Qualification Criteria

AURA selects Beacons based on:

  1. Category match: Beacon serves requested product category
  2. Hard constraint capability: Beacon can satisfy all hard constraints
  3. Business rule compliance (Phase 7): Scout principal meets Beacon’s business rules — verification level, consent tier, jurisdiction, transaction count. Beacons whose rules would reject the Scout are excluded before offer requests are sent.
  4. Minimum reputation: Beacon reputation ≥ 60 (configurable)
  5. Capacity: Beacon has not exceeded rate limits
  6. Geographic coverage: Beacon ships to Scout’s location
  7. Settlement compatibility (Phase 7): Beacon accepts at least one of Scout’s settlement_preference.preferred_methods. If no overlap, Beacon is excluded.

8. Beacon Response Protocol

8.1 Submitting Offers

Beacon submits offers to the provided response URL:

POST /v1/sessions/{session_id}/offers

Request:

{
  "request_id": "req_01HXYZ...",
  "beacon_id": "bcn_01HXYZ...",
  "offers": [
    {
      "offer_id": "ofr_01HABC...",
      "product": {
        "product_id": "prod_sony_wh1000xm5",
        "name": "Sony WH-1000XM5 Wireless Noise Canceling Headphones",
        "category": "electronics.headphones.over_ear",
        "structured_attributes": {
          "brand": "Sony",
          "model": "WH-1000XM5",
          "color": "black",
          "connectivity": "bluetooth_5.2",
          "features": ["noise_cancellation", "wireless", "foldable", "multipoint", "speak_to_chat"],
          "battery_hours": 30,
          "weight_grams": 250,
          "driver_size_mm": 30
        },
        "natural_language_description": {
          "content": "Our flagship noise-canceling headphones, perfect for commuters who demand the best. Industry-leading noise cancellation automatically optimizes based on your environment. 30-hour battery life gets you through the longest trips. Premium comfort with soft-fit leather and lightweight design at only 250g. Seamless switching between devices with multipoint connection. Speak-to-Chat pauses music when you talk. Ideal for the discerning audio enthusiast who won't compromise on quality.",
          "language": "en"
        }
      },
      "pricing": {
        "currency": "USD",
        "list_price": 399.99,
        "offer_price": 349.99,
        "discount_percentage": 12.5,
        "price_valid_until": "2026-01-14T22:00:00Z",
        "price_rationale": "Loyal customer appreciation pricing"
      },
      "availability": {
        "in_stock": true,
        "quantity_available": 45,
        "estimated_ship_date": "2026-01-15",
        "delivery_estimate_days": {"min": 2, "max": 5},
        "shipping_options": [
          {"method": "standard", "days": "3-5", "price_usd": 0},
          {"method": "express", "days": "1-2", "price_usd": 14.99}
        ]
      },
      "terms": {
        "return_policy": "30-day free returns, no questions asked",
        "warranty": "1-year manufacturer warranty, extendable",
        "price_match": true
      },
      "valid_until": "2026-01-14T22:00:00Z"
    }
  ],
  "beacon_metadata": {
    "merchant_name": "Acme Electronics",
    "merchant_url": "https://acme-electronics.example.com",
    "support_email": "support@acme-electronics.example.com",
    "certifications": ["bbb_accredited", "google_trusted_store"]
  },
  "signature": "sig_beacon_..."
}

8.2 Offer Signature

Beacons MUST sign offers to ensure authenticity and prevent tampering.

8.2.1 Canonical Signature Payload

The signature payload is formed by joining fields with a newline (\n) delimiter. Field order is normative — implementations MUST use exactly this sequence:

signature_payload = offer_id + "\n"
                  + beacon_id + "\n"
                  + product_id + "\n"
                  + offer_price + "\n"
                  + currency + "\n"
                  + valid_until + "\n"
                  + payment_terms_hash

signature = Ed25519.sign(signature_payload, beacon_private_key)

(Phase 7) The payment_terms_hash is a SHA-256 hash of the canonical JSON representation of the payment_terms object. This ensures the Beacon cannot retroactively claim it offered different terms. If no payment_terms are present (pre-Phase 7 offers), the field is omitted and valid_until remains the last field.

payment_terms_hash = SHA256(JSON.stringify(payment_terms, Object.keys(payment_terms).sort()))

All fields are serialised as UTF-8 strings. Numeric fields (offer_price) use their decimal string representation with no trailing zeros beyond two decimal places (e.g., "349.99", not "349.990").

Why newline-delimited? The v1.0 spec used bare concatenation (offer_id + beacon_id + ...) which is ambiguous — there is no way to distinguish where one field ends and the next begins. For example, offer_id="ofr_ab" + beacon_id="cd" produces the same payload as offer_id="ofr_a" + beacon_id="bcd". Newline delimiters eliminate this class of collision.

Worked example:

# Fields
offer_id    = "ofr_01HABC"
beacon_id   = "bcn_02HXYZ"
product_id  = "prod_WH1000XM5"
offer_price = "349.99"
currency    = "USD"
valid_until = "2026-01-14T10:30:00Z"

# Payload (32 bytes of field data + 5 newline delimiters)
"ofr_01HABC\nbcn_02HXYZ\nprod_WH1000XM5\n349.99\nUSD\n2026-01-14T10:30:00Z"

# Signature
Ed25519.sign(payload, beacon_private_key) → "sig_MEUCIQDx..."

8.2.2 Signature Verification

AURA Core verifies Beacon signatures before presenting offers to Scouts. The Beacon’s Ed25519 public key (registered during Beacon onboarding) is used for verification.

8.2.3 Core Counter-Signature (Not Yet Implemented)

AURA Core does not currently counter-sign offers before presenting them to Scouts. This means a Beacon could theoretically claim it submitted an offer that Core never received, since only the Beacon’s signature exists.

A future protocol version will add a Core counter-signature: after verifying the Beacon’s signature, Core appends its own Ed25519 signature over the Beacon-signed payload plus a Core-assigned receipt timestamp. This provides non-repudiation — the Scout can verify that Core received and relayed the offer, and the Beacon can verify that Core presented its offer unmodified.

# Future: Core counter-signature (reserved, not yet implemented)
core_payload = beacon_signature + "\n" + core_receipt_timestamp
core_counter_signature = Ed25519.sign(core_payload, core_private_key)

8.3 Response Timeout Handling

8.4 Multi-Offer Submissions

Beacons MAY submit multiple offers per request (e.g., different product variants, pricing tiers):

{
  "offers": [
    { "offer_id": "ofr_01HABC...", "product": {...}, "pricing": {"offer_price": 349.99} },
    { "offer_id": "ofr_01HDEF...", "product": {...}, "pricing": {"offer_price": 279.99} },
    { "offer_id": "ofr_01HGHI...", "product": {...}, "pricing": {"offer_price": 199.99} }
  ]
}

Maximum offers per Beacon per session: 5 (configurable).

8.5 Beacon Webhook Events

Beacons receive notifications from AURA Core via webhooks. This mechanism enables semi-autonomous Beacon behavior, including proactive notifications and event-driven responses.

8.5.1 Webhook Registration

Beacons specify their webhook URL during registration. AURA sends HTTP POST requests to this URL for all events.

Webhook Security:

8.5.2 Webhook Event Types

Event Type Description Beacon Action Required
offer_request New offer request from Scout Generate and submit offers
offer_accepted Scout committed to Beacon’s offer Prepare for fulfillment
transaction_confirmed Payment successfully processed Begin fulfillment
transaction_cancelled Transaction cancelled by Scout Cancel pending fulfillment
transaction_completed Order delivered, transaction closed Update records
policy_violation Beacon offer violated Scout/AURA policy Review and adjust offers
reputation_updated Beacon reputation score changed Informational

8.5.3 Webhook Payload Structure

All webhooks follow a standard envelope:

{
  "event_id": "evt_01HXYZ...",
  "event_type": "offer_accepted",
  "timestamp": "2026-01-14T10:35:00Z",
  "beacon_id": "bcn_01HXYZ...",
  "payload": {
    // Event-specific data
  },
  "signature": "sig_aura_..."
}

8.5.4 Event: offer_request

Sent when AURA routes a Scout request to this Beacon:

{
  "event_type": "offer_request",
  "payload": {
    "request_id": "req_01HXYZ...",
    "session_id": "ses_01HXYZ...",
    "respond_by": "2026-01-14T10:00:42Z",
    "response_url": "https://api.aura.example.com/v1/sessions/ses_01HXYZ.../offers",
    "interpreted_request": {
      "structured_requirements": {...},
      "natural_language_context": {...}
    }
  }
}

8.5.5 Event: offer_accepted

Sent when Scout commits to this Beacon’s offer:

{
  "event_type": "offer_accepted",
  "payload": {
    "offer_id": "ofr_01HABC...",
    "session_id": "ses_01HXYZ...",
    "transaction_id": "txn_01HXYZ...",
    "quantity": 1,
    "buyer_identity": {
      "name": "Jane Doe",
      "email": "jane.doe@example.com"
    },
    "shipping_address": {...},
    "payment_pending": true
  }
}

8.5.6 Proactive Beacon Notifications (Future Extension)

The webhook mechanism is designed to support future proactive Beacon behaviors:

These extensions will be defined in future protocol versions.


9. Offer Ranking & Delivery

9.1 Compatibility-Weighted Reputation (CWR)

AURA ranks offers using CWR, which balances base reputation with Scout-specific compatibility, adjusted by clearinghouse risk assessment (Phase 7):

CWR = ((Base_Reputation × 0.6) + (Compatibility_Score × 0.4)) × Risk_Adjustment

Where:

Base_Reputation (0-100):

Compatibility_Score (0-100):

Compatibility_Score = (Structured_Match × 0.5) + (Semantic_Similarity × 0.5)

Structured_Match: How well the offer’s structured attributes match Scout’s requirements Semantic_Similarity: LLM-computed similarity between Scout’s context and offer description

Risk_Adjustment (0.0–1.0) — Phase 7:

The risk adjustment factor penalizes offers from Beacons with elevated clearing risk. It is computed from the Beacon’s bilateral risk profile (Section 10.7.1) and ensures that risk costs are reflected in ranking, not just in margin:

Risk_Adjustment = 1.0 - (Beacon_Risk_Score × Risk_Weight)

Where:

A Beacon with a perfect risk score (0.0) receives Risk_Adjustment = 1.0 (no penalty). A Beacon at the maximum risk score (1.0) with default weight receives Risk_Adjustment = 0.7 (30% CWR reduction).

Pre-Phase 7 behavior: When clearinghouse risk assessment is not active, Risk_Adjustment = 1.0 (identity multiplier). The formula degrades gracefully to the original CWR calculation.

9.1.1 Business Rule Pre-Filtering

Before CWR ranking, offers that fail either the Beacon’s business rules (Section 3.1.5) or the Scout’s acceptance criteria are excluded from the ranked set. These offers are not ranked lower — they are removed entirely.

Excluded offers are available via a separate query parameter:

GET /v1/sessions/{session_id}/offers?include_excluded=true

Excluded offers include a structured exclusion_reason:

{
  "offer_id": "ofr_01HABC...",
  "excluded": true,
  "exclusion_reason": {
    "code": "BUSINESS_RULE_VIOLATION",
    "rule_type": "min_trust_level",
    "rejected_by": "beacon",
    "message": "Beacon requires entity_verified for transactions over $1,000"
  }
}

9.2 CWR Calculation Example

Scout seeking: wireless headphones for train commute, Sony preference, $300-400

Beacon A Offer: Sony WH-1000XM5, $349.99, Base_Reputation: 87
  Structured_Match: 95% (all features, right price range, preferred brand)
  Semantic_Similarity: 92% (commute-focused description, noise emphasis)
  Compatibility_Score: (0.95 × 0.5) + (0.92 × 0.5) = 93.5
  Beacon_Risk_Score: 0.10 (low risk — established Beacon, low dispute rate)
  Risk_Adjustment: 1.0 - (0.10 × 0.3) = 0.97
  CWR = ((87 × 0.6) + (93.5 × 0.4)) × 0.97 = 89.6 × 0.97 = 86.9

Beacon B Offer: Bose QuietComfort, $299.99, Base_Reputation: 92
  Structured_Match: 80% (all features, good price, acceptable brand)
  Semantic_Similarity: 78% (general description, less commute-specific)
  Compatibility_Score: (0.80 × 0.5) + (0.78 × 0.5) = 79.0
  Beacon_Risk_Score: 0.05 (very low risk — long history, near-zero disputes)
  Risk_Adjustment: 1.0 - (0.05 × 0.3) = 0.985
  CWR = ((92 × 0.6) + (79 × 0.4)) × 0.985 = 86.8 × 0.985 = 85.5

Beacon C Offer: Audio-Technica ATH-M50x, $299.99, Base_Reputation: 78
  Structured_Match: 70% (some features, acceptable price, non-preferred brand)
  Semantic_Similarity: 65% (studio-focused, less commute relevance)
  Compatibility_Score: (0.70 × 0.5) + (0.65 × 0.5) = 67.5
  Beacon_Risk_Score: 0.45 (elevated — new Beacon, limited history, recent dispute)
  Risk_Adjustment: 1.0 - (0.45 × 0.3) = 0.865
  CWR = ((78 × 0.6) + (67.5 × 0.4)) × 0.865 = 73.8 × 0.865 = 63.8

Result: Beacon A ranked highest. Beacon C's elevated risk score compounds its
lower compatibility, pushing it further down. Risk adjustment prevents high-risk
Beacons from competing on reputation alone.

9.3 Retrieving Ranked Offers

Scout retrieves ranked offers:

GET /v1/sessions/{session_id}/offers

Response (200 OK):

{
  "session_id": "ses_01HXYZ...",
  "status": "offers_ready",
  "total_offers": 8,
  "offers": [
    {
      "rank": 1,
      "offer_id": "ofr_01HABC...",
      "cwr_score": 86.9,
      "cwr_components": {
        "base_reputation": 87,
        "compatibility_score": 93.5,
        "risk_adjustment": 0.97,
        "beacon_risk_score": 0.10
      },
      "beacon_id": "bcn_01HXYZ...",
      "product": {
        "name": "Sony WH-1000XM5",
        "category": "electronics.headphones.over_ear"
      },
      "pricing": {
        "currency": "USD",
        "offer_price": 349.99,
        "list_price": 399.99
      },
      "availability": {
        "in_stock": true,
        "delivery_estimate_days": {"min": 2, "max": 5}
      },
      "merchant": {
        "name": "Acme Electronics",
        "reputation_score": 87
      },
      "match_explanation": {
        "summary": "Top match: preferred brand Sony, excellent noise cancellation, within budget, commuter-friendly features",
        "structured_match_score": 95,
        "semantic_similarity_score": 92
      },
      "detail_url": "/v1/offers/ofr_01HABC..."
    },
    {
      "rank": 2,
      "offer_id": "ofr_01HDEF...",
      "cwr_score": 86.8,
      "beacon_id": "bcn_02HXYZ...",
      "product": {
        "name": "Bose QuietComfort Ultra",
        "category": "electronics.headphones.over_ear"
      },
      "pricing": {
        "currency": "USD",
        "offer_price": 299.99,
        "list_price": 379.99
      },
      "match_explanation": {
        "summary": "Strong alternative: excellent noise cancellation, better price point, highly-rated merchant",
        "structured_match_score": 80,
        "semantic_similarity_score": 78
      },
      "detail_url": "/v1/offers/ofr_01HDEF..."
    }
  ],
  "ranking_metadata": {
    "algorithm_version": "cwr_v2",
    "computed_at": "2026-01-14T10:00:35Z"
  }
}

9.4 Offer Detail Retrieval

Scout can retrieve full offer details:

GET /v1/offers/{offer_id}

Returns the complete Offer object (see Section 4.4).