> ## Documentation Index
> Fetch the complete documentation index at: https://docs.qwedai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# QWED UCP guards for AI commerce verification

> Reference for QWED UCP guards including Money Guard, State Guard, Refund Guard, and Attestation Guard for AI commerce verification.

QWED-UCP includes **10 verification guards** that validate different aspects of UCP checkout data.

***

## 1. Money guard

**Verifies the total formula is mathematically correct.**

```
Total = Subtotal - Discount + Tax + Shipping + Fee
```

### Usage

```python theme={null}
driver = MoneyGuard()
result = driver.verify_cart_totals(
    line_items=[{"price": 35.00, "quantity": 2}, {"price": 15.00, "quantity": 1}],
    taxes=8.25,
    discounts=10.00,
    claimed_total=98.25
)
# Returns: {"verified": True}
```

### Tolerance

Uses `Decimal` precision with 1 cent (\$0.01) tolerance for floating-point errors.

***

## 2. State guard

**Verifies valid checkout state machine transitions.**

### Valid states

```
incomplete → ready_for_complete → completed
                              ↓
                            failed
                              ↓
                           cancelled
```

### Usage

```python theme={null}
from qwed_ucp.guards.state_guard import StateGuard

guard = StateGuard()
# Check if we can SHIP given the current state is PAID
result = guard.verify_transition(
    current_state="paid",
    action="ship"
)
# Returns: {"verified": True}
```

### Rules

* `incomplete`: Can be empty
* `ready_for_complete`: Must have line items
* `completed`: Must have order object
* Cannot transition backwards

***

## 3. Schema guard

**Validates UCP JSON schema compliance.**

### Usage

```python theme={null}
from qwed_ucp.guards import SchemaGuard

guard = SchemaGuard()
result = guard.verify(checkout_data)
```

### Validates

* Required fields present
* Correct types (string, number, array)
* Valid enum values (status, total types)

***

## 4. Line items guard

**Verifies price × quantity = line total for each item.**

### Usage

```python theme={null}
from qwed_ucp.guards import LineItemsGuard

guard = LineItemsGuard()
result = guard.verify({
    "line_items": [
        {"id": "roses", "quantity": 2, "item": {"price": 35.00}},
        {"id": "pot", "quantity": 1, "item": {"price": 15.00}}
    ],
    "totals": [{"type": "subtotal", "amount": 85.00}]  # 2×35 + 1×15 = 85 ✓
})
```

### Checks

* Each item: `price × quantity = line_total`
* Sum of line items = subtotal
* Quantities must be positive integers
* Prices must be non-negative

***

## 5. Discount guard

**Verifies percentage and fixed discount calculations.**

### Usage - percentage discount

```python theme={null}
from qwed_ucp.guards import DiscountGuard
from decimal import Decimal

guard = DiscountGuard()
result = guard.verify_percentage_discount(
    subtotal=Decimal("100.00"),
    discount_amount=Decimal("10.00"),
    percentage=Decimal("10")  # 10% of 100 = 10 ✓
)
```

### Usage - fixed discount

```python theme={null}
result = guard.verify_fixed_discount(
    subtotal=Decimal("50.00"),
    discount_amount=Decimal("5.00")  # Fixed $5 off ✓
)
```

### Rules

* Percentage: Must be 0-100%
* Fixed: Cannot exceed subtotal
* Discount must be non-negative

***

## 6. Currency guard

**Validates ISO 4217 currency codes and format.**

### Usage

```python theme={null}
from qwed_ucp.guards import CurrencyGuard

guard = CurrencyGuard()
result = guard.verify({"currency": "USD"})
```

### Validates

* 3-letter ISO 4217 codes (USD, EUR, GBP, JPY, etc.)
* Zero-decimal currencies (JPY, KRW) have no decimals
* Currency conversion accuracy

### Zero-decimal currencies

```python theme={null}
# Valid - no decimals
{"currency": "JPY", "totals": [{"type": "total", "amount": 1000}]}

# Invalid - JPY shouldn't have decimals
{"currency": "JPY", "totals": [{"type": "total", "amount": 1000.50}]}
```

***

## 7. Refund guard

**Verifies refund amounts match original transactions.**

### Usage - full refund

```python theme={null}
from qwed_ucp.guards.refund import RefundGuard
from decimal import Decimal

guard = RefundGuard()
result = guard.verify_full_refund(
    original_total=Decimal("100.00"),
    refund_amount=Decimal("100.00")
)
# Returns: RefundGuardResult(verified=True, details={"refund_type": "full"})
```

### Usage - partial refund

```python theme={null}
result = guard.verify_partial_refund(
    original_total=Decimal("100.00"),
    refund_amount=Decimal("50.00"),
    percentage=Decimal("50")  # 50% of 100 = 50 ✓
)
```

### Usage - tax reversal

```python theme={null}
result = guard.verify_tax_reversal(
    original_tax=Decimal("10.00"),
    refund_tax=Decimal("5.00"),
    refund_percentage=Decimal("50")  # 50% of tax reversed ✓
)
```

### Usage - checkout refund

```python theme={null}
checkout = {"totals": [{"type": "total", "amount": 100.00}]}
refund = {"amount": 100.00, "type": "full"}
result = guard.verify(checkout, refund)
```

### Rules

* Full refund must exactly match original total
* Partial refund percentage must be 0-100%
* Refund cannot exceed original total
* Tax reversal must be proportional to the refund percentage

***

## 8. Tip guard

**Verifies tip calculations (pre-tax and post-tax).**

### Usage - pre-tax tip

```python theme={null}
from qwed_ucp.guards.tip import TipGuard
from decimal import Decimal

guard = TipGuard()
result = guard.verify_percentage_tip(
    subtotal=Decimal("50.00"),
    tip_amount=Decimal("9.00"),
    percentage=Decimal("18")  # 18% of 50 = 9 ✓
)
# Returns: TipGuardResult(verified=True, details={"tip_type": "pre-tax"})
```

### Usage - post-tax tip

```python theme={null}
result = guard.verify_post_tax_tip(
    total=Decimal("108.00"),
    tip_amount=Decimal("21.60"),
    percentage=Decimal("20")  # 20% of 108 = 21.60 ✓
)
# Returns: TipGuardResult(verified=True, details={"tip_type": "post-tax"})
```

### Usage - bounds check

```python theme={null}
result = guard.verify_tip_bounds(
    tip_amount=Decimal("20.00"),
    base_amount=Decimal("100.00")
)
```

### Rules

* Tip percentage must be 0-100%
* Tip cannot be negative
* Tip cannot exceed 100% of the base amount
* Supports both pre-tax (subtotal) and post-tax (total) calculations

***

## 9. Fee guard

**Verifies fee calculations (service, delivery, platform).**

### Usage - service fee

```python theme={null}
from qwed_ucp.guards.fee import FeeGuard
from decimal import Decimal

guard = FeeGuard()
result = guard.verify_service_fee(
    subtotal=Decimal("100.00"),
    fee_amount=Decimal("5.00"),
    percentage=Decimal("5")  # 5% of 100 = 5 ✓
)
# Returns: FeeGuardResult(verified=True, details={"fee_type": "service"})
```

### Usage - delivery fee

```python theme={null}
# Formula: base_fee + (distance × rate_per_km)
result = guard.verify_delivery_fee(
    claimed_fee=Decimal("13.00"),
    distance_km=Decimal("5"),
    rate_per_km=Decimal("2.00"),
    base_fee=Decimal("3.00")  # 3 + 5×2 = 13 ✓
)
# Returns: FeeGuardResult(verified=True, details={"fee_type": "delivery"})
```

### Usage - platform fee

```python theme={null}
result = guard.verify_platform_fee(
    fee_amount=Decimal("15.00"),
    subtotal=Decimal("100.00"),
    max_percentage=Decimal("30")  # 15% < 30% max ✓
)
```

### Rules

* Fee percentage cannot be negative
* Distance and rate cannot be negative
* Platform fee cannot be negative
* Platform fee cannot exceed the configured maximum percentage (default 30%)

***

## 10. Attestation guard

**Generates cryptographic proofs (JWTs) for verification results.**

### Usage - sign a checkout

```python theme={null}
from qwed_ucp.guards.attestation import AttestationGuard

# Production: provide a secret key or set QWED_ATTESTATION_SECRET env var
guard = AttestationGuard(secret_key="your-secret-key")

# Dev mode: use allow_insecure=True (generates a random secret)
guard = AttestationGuard(allow_insecure=True)

result = guard.sign_checkout(
    checkout={"currency": "USD", "totals": [{"type": "total", "amount": 82.79}]},
    verification_result={"verified": True},
    guards_passed=["MoneyGuard", "StateGuard", "LineItemsGuard"]
)

print(result.token)    # JWT token string
print(result.verified) # True
print(result.details)  # {"checkout_hash": "...", "issued_at": ..., "expires_at": ...}
```

### Usage - verify an attestation

```python theme={null}
result = guard.verify_attestation(token="eyJ...")

print(result.verified)  # True if valid and not expired
print(result.details)   # Decoded JWT payload
```

### Usage - create a receipt

```python theme={null}
receipt = guard.create_receipt(
    checkout=checkout_data,
    verification_result={"verified": True}
)

print(receipt["receipt_id"])          # "QWED-A1B2C3D4..."
print(receipt["verified"])            # True
print(receipt["engine"])              # "QWED-Deterministic-v1"
print(receipt["verification_mode"])   # "deterministic"
```

### JWT payload fields

| Field               | Type     | Description                                  |
| ------------------- | -------- | -------------------------------------------- |
| `iss`               | `string` | Always `"qwed-ucp-attestation"`              |
| `iat`               | `int`    | Issued-at Unix timestamp                     |
| `exp`               | `int`    | Expiration timestamp (1 hour after issuance) |
| `checkout_hash`     | `string` | SHA-256 hash of the checkout object          |
| `verified`          | `bool`   | Whether the checkout passed verification     |
| `guards_passed`     | `array`  | List of guard names that passed              |
| `errors`            | `array`  | List of errors (if any)                      |
| `engine`            | `string` | `"QWED-Deterministic-v1"`                    |
| `verification_mode` | `string` | `"deterministic"`                            |

<Warning>
  In production, set `QWED_ATTESTATION_SECRET` as an environment variable or pass `secret_key` directly. Without a secret, initialization raises a `ValueError` unless `allow_insecure=True` or the `QWED_DEV_MODE=1` env var is set.
</Warning>

***

## Verification result fields

All guard results and `UCPVerificationResult` include:

| Field               | Type     | Description                                |
| ------------------- | -------- | ------------------------------------------ |
| `verified`          | `bool`   | Whether verification passed                |
| `engine`            | `string` | `"QWED-Deterministic-v1"`                  |
| `verification_mode` | `string` | `"deterministic"`                          |
| `error`             | `string` | Error message (when `verified` is `false`) |

***

## Running all guards

Use `UCPVerifier` to run all guards at once:

```python theme={null}
from qwed_ucp import UCPVerifier

verifier = UCPVerifier()
result = verifier.verify_checkout(checkout_data)

print(f"Verified: {result.verified}")
print(f"Engine: {result.engine}")                     # "QWED-Deterministic-v1"
print(f"Mode: {result.verification_mode}")             # "deterministic"
print(f"Guards passed: {len([g for g in result.guards if g.verified])}")
```
