# WSA Knowledge Base

> Auto-generated. Do not edit manually.

> 🤖 Want AI to read this page? Point it to [`/knowledge-base/knowledge-base.md`](/knowledge-base/knowledge-base.md)
>
> 📦 [Source](https://code.amazon.com/packages/WarrantyServicesDocumentation)

## Table of Contents

1. [Customer Issues](#1-customer-issues)
   1. [SOP: Astro Dormant Warranty Revival](#11-sop-astro-dormant-warranty-revival)
   2. [SOP: Bundled Device Warranty Issues](#12-sop-bundled-device-warranty-issues)
   3. [SOP: Certified Refurbished Device Warranty Issues](#13-sop-certified-refurbished-device-warranty-issues)
   4. [SOP: Claim Resolution Issues](#14-sop-claim-resolution-issues)
   5. [SOP: Extended Warranty Missing or Invalid State](#15-sop-extended-warranty-missing-or-invalid-state)
   6. [SOP: G2S2 Extended Warranty Configuration Fallback](#16-sop-g2s2-extended-warranty-configuration-fallback)
   7. [SOP: Inactive Binding on Expired Warranty](#17-sop-inactive-binding-on-expired-warranty)
   8. [SOP: KDSS Order Identification Issues](#18-sop-kdss-order-identification-issues)
   9. [SOP: Warranty Not Bound to Device After Replacement — "Already Been Replaced by a Different Device" (KRIS `IsBundled` gap)](#19-sop-warranty-not-bound-to-device-after-replacement--already-been-replaced-by-a-different-device-kris-isbundled-gap)
   10. [SOP: No Replacement Options Error](#110-sop-no-replacement-options-error)
   11. [SOP: OBA Order Binding Issues](#111-sop-oba-order-binding-issues)
   12. [SOP: Order-Level Replacement and Refund Block Issues](#112-sop-order-level-replacement-and-refund-block-issues)
   13. [SOP: Order Reassignment Issues](#113-sop-order-reassignment-issues)
   14. [SOP: Privacy Compliance DLQ Issues](#114-sop-privacy-compliance-dlq-issues)
   15. [SOP: "Already Claimed" / "Not Bound" After a Mid-Chain Claim Cancellation](#115-sop-already-claimed--not-bound-after-a-mid-chain-claim-cancellation)
   16. [SOP: Unable to Determine Original ASIN](#116-sop-unable-to-determine-original-asin)
   17. [SOP: Warranty Binding Issues](#117-sop-warranty-binding-issues)
   18. [SOP: Warranty Deletion Issues (Old Devices)](#118-sop-warranty-deletion-issues-old-devices)
   19. [SOP: Warranty Type & Configuration Mismatches](#119-sop-warranty-type--configuration-mismatches)
   20. [SOP: WSA Self Replacement Null Fields](#120-sop-wsa-self-replacement-null-fields)
2. [Alarms](#2-alarms)
   1. [SOP: 5XX TransferLW for CanceledClaim Alarm](#21-sop-5xx-transferlw-for-canceledclaim-alarm)
   2. [SOP: DynamoDB High TPS Alarm Analysis](#22-sop-dynamodb-high-tps-alarm-analysis)
   3. [SOP: Missing Marketplace Configuration Alarm](#23-sop-missing-marketplace-configuration-alarm)
   4. [SOP: OverwritingUnitOfWorkOperationRequest Alarm](#24-sop-overwritingunitofworkoperationrequest-alarm)
   5. [SOP: Replacement Product for Already-Bound Binding Alarm (KRIS `IsBundled` gap)](#25-sop-replacement-product-for-already-bound-binding-alarm-kris-isbundled-gap)
3. [Human-Only Documentation](#3-human-only-documentation)
   1. [Andes Table Data Quality Issues](#31-andes-table-data-quality-issues)
   2. [DMS Event Subscription Migration (V1 → V2) — Operations SOP](#32-dms-event-subscription-migration-v1--v2--operations-sop)
   3. [Edge Cases (Manual Fixes)](#33-edge-cases-manual-fixes)
   4. [G2S2 & RMP Configuration](#34-g2s2--rmp-configuration)
   5. [Infrastructure Emergencies](#35-infrastructure-emergencies)
   6. [Oncall Reference](#36-oncall-reference)
   7. [Pipeline & Deployment](#37-pipeline--deployment)
   8. [Privacy Compliance (Boomerang / AEDU / SandFire)](#38-privacy-compliance-boomerang--aedu--sandfire)

---

## 1. Customer Issues

<details>
<summary>

### 1.1. SOP: Astro Dormant Warranty Revival

</summary>


#### Applicability

**Use this SOP when:**
- Ticket mentions Astro device warranty issues
- Warranty lookup shows "Dormant Warranty" indicator
- Customer cannot use warranty coverage on Astro device

**DO NOT use if:**
- Issue is about "Astro Workflow" (different system)
- Device is not an Astro device
- Warranty is not in dormant state
- The device is a **replacement** that has NO warranty and `GET_WARRANTY_CLAIM_CODE` returns *"…already been replaced by a different device"* — that is the KRIS `IsBundled` orphaned-replacement case (`bundled-device-warranty` SOP, **Issue Type 5**), NOT dormant revival. Reviving a dormant warranty will not rebind the replacement device.

#### Prerequisites

- Device serial number (DSN) from ticket
- Device type (commonly: `A2MDL5WTJIU8SZ` for Astro)

---

#### Procedure

##### Step 1: Verify Dormant Warranty Status

First, use the API operation to get the CS view of warranties:
```json
{
  "operation": "GET_WARRANTIES_BY_DEVICE",
  "params": { "dsn": "<DSN from ticket>" }
}
```

Note: deviceType is auto-looked up from DIS if not provided.

**Expected:** Response may show warranty issues or missing warranty

**If warranty shows normally:** This SOP may not apply.

---

##### Step 2: Query DormantWarranty Table

Use the direct operation to check for dormant warranties:
```json
{
  "operation": "QUERY_DORMANT_WARRANTIES",
  "params": { "dsn": "<DSN from ticket>" }
}
```

Note: deviceType is auto-looked up from DIS if not provided.

**Expected:** Returns dormant warranty record with `warrantyId`

---

##### Step 3: Get Event History (Optional)

If you need to understand what happened to the warranty:
```json
{
  "operation": "QUERY_EVENT_SOURCE",
  "params": { "warrantyId": "<warranty ID from step 2>" }
}
```

This shows the full audit trail of warranty events.

---

##### Step 4: Extract Required Information

From query results:
- `warrantyId` - Format: `Warranty-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX` or `Warranty-NUMERIC`

Dates are computed automatically:
- `expirationDate` - 3 months before today
- `startDate` - 1 year before the expiration date

---

##### Step 5: Execute Revival

**REVIVE_DORMANT_WARRANTY is automated for Astro devices (type A2MDL5WTJIU8SZ).**

The agent computes the dates automatically and delegates to OncallOperationsHandler:
```json
{
  "operation": "REVIVE_DORMANT_WARRANTY",
  "params": {
    "warrantyId": "<warranty ID>",
    "dsn": "<DSN from ticket>"
  }
}
```

The handler will:
1. Verify the device is Astro type (A2MDL5WTJIU8SZ) via DIS lookup
2. Compute `expirationDate` = today - 3 months, `startDate` = expirationDate - 1 year
3. Delegate to OncallOperationsHandler with the computed dates

**Non-Astro devices** still require manual oncall execution.

---

##### Step 6: Verification (Post-Revival)

Use the API operation to verify the warranty is now active:
```json
{
  "operation": "GET_WARRANTIES_BY_DEVICE",
  "params": { "dsn": "<DSN>" }
}
```

**Verify:**
- Warranty shows as active LIMITED_WARRANTY (not dormant)
- Correct `startDate` and `expirationDate`
- `customerId` is associated

---

#### Stop Conditions

Escalate if:
- Device is not Astro type
- No dormant warranty record found
- Cannot determine appropriate dates
- Any tool error

---

#### Example

**Ticket:** V2056018398 - Astro device warranty not working

**Resolution:**
1. Queried device - confirmed dormant indicator
2. Found Warranty-abc123-def456 in DormantWarranties table
3. Prepared revival payload, escalated for manual execution
4. Engineer executed, verification confirmed active warranty

---

#### Region Reference

| Marketplace | Region |
|-------------|--------|
| NA | us-east-1 |
| EU | eu-west-1 |
| FE | us-west-2 |

</details>

---

<details>
<summary>

### 1.2. SOP: Bundled Device Warranty Issues

</summary>


#### Applicability

**Use this SOP when:**
- Issue involves Fire TV Stick/Cube with accessory remote
- Issue involves Echo Buds (Puget/Powell) with multiple components
- Warranty missing for a bundled component
- EW not binding to replacement bundled device

**DO NOT use if:**
- Device is not a bundled device (single-component device)
- Issue is about replacement options availability (use no-replacement-options SOP)
- Issue is about EW binding to wrong device (use warranty-binding SOP)

#### Prerequisites

- Device serial number (DSN) of the base device
- Component information (which part needs replacement)

---

#### Key Concept: Bundled Devices

Bundled devices (e.g., Fire TV + Remote) share a single Limited Warranty bound to the base device DSN. Claims can be made against this single warranty to replace either the base device or the accessory. Only the base device has a DSN bound to the warranty.

---

#### Issue Type 1: Missing Warranty on Bundled Base Unit

##### When to Use
- Base device has no warranty
- KDSS fulfillment may have been missed for the bundle

##### Procedure

**Step 1: Check Warranty State**

```json
{
  "operation": "GET_WARRANTIES_BY_DEVICE",
  "params": { "dsn": "<BASE_DSN>" }
}
```

**Step 2: Attempt Backfill**

```json
{
  "operation": "BACKFILL_LIMITED_WARRANTY",
  "params": { "dsn": "<BASE_DSN>" }
}
```

**Step 3: If Backfill Fails — Check Shipments**

```json
{
  "operation": "GET_DEVICE_SHIPMENTS",
  "params": { "dsn": "<BASE_DSN>" }
}
```

If shipment data exists but KDSS didn't fulfill, escalate to oncall engineer to construct and send a KDSS SQS payload (see kdss-order-identification SOP advanced path).

If no shipment data exists, reassign to KDSS: Digital Media Technology > Kindle Device Sales > KindleDeviceSalesService.

---

#### Issue Type 2: EW Not Bound to Replacement Bundled Device

##### When to Use
- Claim was made on bundled device, replacement has different Device Type
- **Extended Warranty (EW)** stayed on old device, didn't transfer to replacement
- Replacement Device Type may not be registered as a Bundled Base Unit in WSA

> **Note:** This procedure (`INVALIDATE_BINDING` + `BIND_EXTENDED_WARRANTY`) is for **Extended Warranties only**. If a **Limited / Worry-Free** warranty is stranded on the original device after a bundled-base-unit replacement (replacement device has no warranty, claim-code 500s), use **the [`kris-isbundled-orphaned-replacement`](../kris-isbundled-orphaned-replacement/README.md) SOP** — `BIND_EXTENDED_WARRANTY` does not apply to limited warranties.

##### Procedure

**Step 1: Verify Both Devices**

```json
{
  "operation": "GET_WARRANTIES_BY_DEVICE",
  "params": { "dsn": "<OLD_DSN>" }
}
```
```json
{
  "operation": "GET_WARRANTIES_BY_DEVICE",
  "params": { "dsn": "<NEW_DSN>" }
}
```

Confirm EW is still bound to old device.

**Step 2: Invalidate Old Binding**

```json
{
  "operation": "INVALIDATE_BINDING",
  "params": {
    "warrantyId": "<EW_WARRANTY_ID>",
    "bindingId": "<OLD_BINDING_ID>"
  }
}
```

**Step 3: Bind to New Device**

```json
{
  "operation": "BIND_EXTENDED_WARRANTY",
  "params": {
    "warrantyId": "<EW_WARRANTY_ID>",
    "dsn": "<NEW_DSN>",
    "deviceType": "<NEW_DEVICE_TYPE>",
    "orderId": "<ORDER_ID>",
    "orderItemId": "<ORDER_ITEM_ID>",
    "orderLineItemId": "<ORDER_LINE_ITEM_ID>",
    "orderUnitId": "<ORDER_UNIT_ID>",
    "marketplaceId": "<MARKETPLACE_ID>"
  }
}
```

**Step 4: Verify**

```json
{
  "operation": "GET_WARRANTIES_BY_DEVICE",
  "params": { "dsn": "<NEW_DSN>" }
}
```

---

#### Issue Type 3: Claim on Base Unit with Stuck Previous Claim (KWS Data)

##### When to Use
- Old KWS claim from before WSA launch is stuck
- Second fulfillment of bundled device failed due to KDSS propagation delay
- Error: "Check if this device has already been replaced by a different device"

> **Disambiguation:** The same *"already been replaced by a different device"* error is also produced by the **KRIS `IsBundled` orphaned-replacement** bug. If the **replacement device has NO active warranty** and the customer's warranty is still bound to the **original** device (its active binding holds the replacement order + the original DSN), that is the **KRIS `IsBundled` orphaned-replacement** scenario, not a stuck KWS claim — use the [`kris-isbundled-orphaned-replacement`](../kris-isbundled-orphaned-replacement/README.md) SOP.

##### Procedure

**Step 1: Check Event History**

```json
{
  "operation": "QUERY_EVENT_SOURCE",
  "params": { "warrantyId": "<WARRANTY_ID>" }
}
```

Look for a stuck `CreateLimitedWarrantyForDeviceShipment` operation.

**Step 2: Escalate to Oncall**

Provide the oncall engineer with:
- The original CreateLW request data from Event Source
- The KDSS SQS payload format needed to re-trigger fulfillment

Oncall must send the corrected KDSS payload to the `KDSSFulfillmentEventsQueue`.

---

#### Issue Type 4: Echo Buds Multi-Component EW Replacement

##### When to Use
- Echo Buds (Puget/Powell) — all components need replacement
- EW can only have one binding, but device has 3 components

##### Procedure

This is an edge case WSA software doesn't handle correctly. An EW can only bind to one component replacement at a time.

**Resolution:** Escalate to oncall engineer. The fix is to extend the limited warranty coverage for the excess components that need replacing. Long-term fix tracked in WSA-1756.

---

#### Issue Type 5: Warranty Stranded on Original Device After Bundled-Base-Unit Replacement (KRIS `IsBundled` gap) — MOVED

> **This scenario now has its own dedicated SOP:
> [`kris-isbundled-orphaned-replacement`](../kris-isbundled-orphaned-replacement/README.md).**

Use that SOP when a customer received a warranty **replacement** device but the warranty stayed on the original device — i.e. the replacement DSN has **no active warranty**, `GET_WARRANTY_CLAIM_CODE` on it **500s** with *"already been replaced by a different device"* (or 409), and the customer's active binding holds the **replacement order + a stale product DSN**. The fix is a device-scoped `UNBIND` of the stale product followed by `BACKFILL_LIMITED_WARRANTY` of the real replacement DSN.

It was split out of this document because its symptoms ("Warranty Not Bound to Device", "already been replaced by a different device") are not bundled-accessory symptoms and were hard to retrieve while buried here.

---

#### Stop Conditions

Escalate if:
- The replacement device belongs to a different customer, or ownership cannot be verified.
- `UNBIND` or `BACKFILL_LIMITED_WARRANTY` errors, or the warranty does not rebind after the isBundled unbind+backfill (see the `kris-isbundled-orphaned-replacement` SOP; durable fix is the KRIS classification correction — KRL-30482 / KRLFRI-97 — after which a fulfillment redrive self-heals).
- Multiple claims are stuck on the same warranty.
- Echo Buds multi-component scenario (always escalate).

</details>

---

<details>
<summary>

### 1.3. SOP: Certified Refurbished Device Warranty Issues

</summary>


#### Applicability

**Use this SOP when:**
- Customer purchased certified refurbished device
- System shows expired warranty from previous owner
- Customer offered OOW discount instead of coverage
- Warranty shows wrong customer ID

**DO NOT use if:**
- Device is new (not refurbished)
- Warranty already belongs to current customer

---

#### GDPR Compliance Requirement

Each customer MUST have their own warranty record.

**Correct workflow:**
1. ✅ Invalidate old warranty (from original owner)
2. ✅ Backfill new warranty (for new customer)
3. ✅ Verify dates (adjust only if FRO sets them wrong)

**❌ NEVER just use `setWarrantyDates` on existing warranty** - violates GDPR

---

#### Procedure

##### Step 1: Verify Current State

**Tool:** `DynamoDBQueryTool.queryByDeviceSerial`
```json
{ "deviceSerialNumber": "<DSN>" }
```

Identify:
- Current warranty ID
- Current customer ID (previous owner)
- Current dates (expired)
- New customer ID (from ticket)

---

##### Step 2: Invalidate Old Warranty

**Tool:** `WSAOncallOperationsTool.invalidateWarranty`
```json
{ "warrantyId": "<OLD_WARRANTY_ID>" }
```

---

##### Step 3: Backfill New Warranty

**Tool:** `WSAOncallOperationsTool.backfillLimitedWarranty`
```json
{
  "deviceSerialNumber": "<DSN>",
  "deviceType": "<DEVICE_TYPE>",
  "customerId": "<NEW_CUSTOMER_ID>"
}
```

FRO will automatically set dates based on device activation.

---

##### Step 4: Verify New Warranty

**Tool:** `DynamoDBQueryTool.queryByDeviceSerial`

Verify:
- New warranty ID exists (different from old)
- Customer ID matches NEW customer
- Start date around purchase/activation
- Expiration = start + 1 year

---

##### Step 5: Adjust Dates (Only If Needed)

**Only if FRO set incorrect dates:**

**Tool:** `WSAOncallOperationsTool.setWarrantyDates`
```json
{
  "warrantyId": "<NEW_WARRANTY_ID>",
  "startDate": "<YYYY-MM-DD>",
  "endDate": "<YYYY-MM-DD>"
}
```

---

#### Example

**Ticket:** D377090790

**Issue:** Customer purchased refurbished Fire Tablet Oct 28, 2025. System showed expired warranty from previous owner.

**Resolution:**
1. Invalidated old warranty (Warranty-092f26d0...)
2. Backfilled new warranty for new customer
3. Verified FRO dates were correct (Oct 30, 2025 - Nov 2, 2026)
4. No date adjustment needed

---

#### Stop Conditions

Escalate if:
- Cannot identify new customer ID
- Device type unclear
- Invalidate or backfill fails
- Multiple active warranties after backfill

</details>

---

<details>
<summary>

### 1.4. SOP: Claim Resolution Issues

</summary>


#### Applicability

**Use this SOP when:**
- Claim was incorrectly canceled and needs to be un-canceled
- Customer received empty box, needs new claim
- Replacement device was fulfilled to wrong customer
- Shipment failed/undeliverable, warranty stuck in "Waiting for replacement"

**DO NOT use if:**
- Issue is about warranty binding (use warranty-binding SOP)
- Issue is about missing warranty (use kdss-order-identification SOP)
- Customer wants to transfer warranty back after keeping original device (use warranty-binding Type 4)

#### Prerequisites

- Device serial number (DSN)
- Warranty ID or Claim ID (if available)

---

#### Issue Type 1: Un-cancel Claim (Mistaken Cancellation)

##### When to Use
- CSA accidentally canceled a claim
- Warranty reverted to previous device but should be on replacement
- Need to undo the cancellation event

##### Procedure

**Step 1: Get Warranty and Claim Details**

```json
{
  "operation": "GET_WARRANTIES_BY_DEVICE",
  "params": { "dsn": "<DSN>" }
}
```

**Step 2: Find the Cancel Transaction**

```json
{
  "operation": "QUERY_EVENT_SOURCE",
  "params": { "warrantyId": "<WARRANTY_ID>" }
}
```

Find the transaction ID associated with the canceled claim event.

**Step 3: Escalate for Rollback**

ROLLBACK_TRANSACTION is a blocked operation. Provide the oncall engineer with:
- Warranty ID
- Transaction ID of the cancel event
- Explanation of why the cancel was incorrect

**Oncall engineer** must use WSA Tools Oncall Operations > Rollback Transaction with the transaction ID. This deletes the cancel events from Event Source, restoring the warranty to the replacement device.

**Step 4: Verify**

```json
{
  "operation": "GET_WARRANTIES_BY_DEVICE",
  "params": { "dsn": "<REPLACEMENT_DSN>" }
}
```

Confirm warranty is now bound to the replacement device.

---

#### Issue Type 2: Empty Box / DRPS No Claim Codes

##### When to Use
- Customer received empty replacement box (missing device)
- CSA tries to issue another replacement, gets "DRPS didn't return any ClaimCodes"
- Previous claim is blocking new claim

##### Procedure

**Step 1: Get Current State**

```json
{
  "operation": "GET_WARRANTIES_BY_DEVICE",
  "params": { "dsn": "<DSN>" }
}
```

Identify the active claim that is blocking.

**Step 2: Cancel the Blocking Claim**

```json
{
  "operation": "CANCEL_CLAIM",
  "params": { "claimId": "<BLOCKING_CLAIM_ID>" }
}
```

**Step 3: Verify**

```json
{
  "operation": "GET_WARRANTIES_BY_DEVICE",
  "params": { "dsn": "<DSN>" }
}
```

Confirm warranty is back on the original device and claim codes are now available. Direct CSA to issue a new claim.

---

#### Issue Type 3: Replacement Fulfilled to Another Customer

##### When to Use
- Customer sent replacement device back to Amazon by mistake
- Amazon re-sold the replacement to a different customer
- Original customer's warranty was invalidated when new customer's warranty was created

##### Procedure

**Step 1: Check Event History**

```json
{
  "operation": "QUERY_EVENT_SOURCE",
  "params": { "warrantyId": "<ORIGINAL_WARRANTY_ID>" }
}
```

Look for:
- `CreateLimitedWarrantyForDeviceShipment` OperationRequestReceived event (from new customer's fulfillment)
- `BindingInvalidated` event
- `WarrantyInvalidated` event

**Step 2: Escalate for Manual DDB Fix**

This requires deleting events from DynamoDB Event Source (blocked operation). Provide the oncall engineer with:
- Warranty ID
- The specific events to delete (the last 2-3 events: CreateLW request, BindingInvalidated, WarrantyInvalidated)
- Timestamps of the events

**Oncall engineer** must delete these events from Event Source, then verify the warranty is restored. After restoration, cancel the claim using WSA Tools.

---

#### Issue Type 4: Shipment Undeliverable / Failed Shipment

##### When to Use
- Replacement device shipment failed delivery
- Device returned to Amazon warehouse
- Warranty shows "Waiting for replacement order"
- Another claim may have been made, creating a stuck state

##### Procedure

**Step 1: Get Warranty State**

```json
{
  "operation": "GET_WARRANTIES_BY_DEVICE",
  "params": { "dsn": "<ORIGINAL_DSN>" }
}
```

**Step 2: Find the Stuck Claim**

```json
{
  "operation": "GET_WARRANTIES_BY_DEVICE",
  "params": { "dsn": "<REPLACEMENT_DSN>" }
}
```

Identify the claim that links the original DSN to the stuck replacement DSN.

**Step 3: Cancel the Stuck Claim**

```json
{
  "operation": "CANCEL_CLAIM",
  "params": { "claimId": "<STUCK_CLAIM_ID>" }
}
```

This releases the original customer's warranty from the failed shipment.

**Step 4: Verify**

```json
{
  "operation": "GET_WARRANTIES_BY_DEVICE",
  "params": { "dsn": "<ORIGINAL_DSN>" }
}
```

Confirm warranty is no longer stuck and customer can proceed with a new replacement.

---

#### Stop Conditions

Escalate if:
- ROLLBACK_TRANSACTION needed (always escalate — blocked operation)
- Manual DDB event deletion needed (always escalate)
- Multiple claims are interleaved on the same warranty
- Replacement device is now owned by a different customer with an active warranty

</details>

---

<details>
<summary>

### 1.5. SOP: Extended Warranty Missing or Invalid State

</summary>


#### Applicability

**Use this SOP when:**
- Customer purchased an extended warranty but it does not exist in WSA
- Extended warranty shows as "refunded" when it was never refunded
- Error: "No extended warranty found for order"

**DO NOT use if:**
- EW exists but won't bind to device (use warranty-binding SOP)
- EW config is missing for an ASIN (use g2s2-config-fallback SOP)
- Issue is about limited warranty (use kdss-order-identification SOP)

#### Prerequisites

- Customer ID or Order ID for the EW purchase
- Ticket creation timestamp

---

#### Issue Type 1: Extended Warranty Never Created (Missed BuyNewEW)

##### When to Use
- Customer purchased EW but no EW record exists in WSA
- Order shows EW purchase but WSA has no corresponding warranty

##### Procedure

**Step 1: Search for EW by Order**

```json
{
  "operation": "GET_EXTENDED_WARRANTIES_BY_ORDER",
  "params": { "orderId": "<ORDER_ID>" }
}
```

**Expected:** Empty result or no matching EW.

**Step 2: Search for EW by Customer**

```json
{
  "operation": "GET_EXTENDED_WARRANTIES_BY_CUSTOMER",
  "params": { "customerId": "<CUSTOMER_ID>" }
}
```

Confirm no EW exists for this purchase.

**Step 3: Escalate for Manual EW Creation**

CREATE_EW is a blocked operation. Provide the oncall engineer with:
- Order ID
- Customer ID
- EW ASIN (from the order/ticket)
- Marketplace ID
- Order date (epoch seconds — use order date, NOT epoch milliseconds)

**Oncall engineer** must use the OncallOperationsLambda `CREATE_EW` operation or manually hit the BuyNewExtendedWarranty API Gateway endpoint with the order data from Grass.

**Step 4: Verify**

```json
{
  "operation": "GET_EXTENDED_WARRANTIES_BY_ORDER",
  "params": { "orderId": "<ORDER_ID>" }
}
```

Confirm EW now exists.

---

#### Issue Type 2: Extended Warranty Incorrectly Refunded

##### When to Use
- EW exists but shows as refunded
- Customer never requested a refund
- Device cannot be replaced because EW is marked refunded

##### Procedure

**Step 1: Verify EW State**

```json
{
  "operation": "GET_EXTENDED_WARRANTIES_BY_CUSTOMER",
  "params": { "customerId": "<CUSTOMER_ID>" }
}
```

Identify the EW that shows as refunded.

**Step 2: Check Event History**

```json
{
  "operation": "QUERY_EVENT_SOURCE",
  "params": { "warrantyId": "<EW_WARRANTY_ID>" }
}
```

Look for a refund event. Verify whether it was legitimate.

**Step 3: Escalate for Manual Fix**

Reactivating a refunded EW requires direct DynamoDB Event Source edits (not available to the agent). Provide the oncall engineer with:
- Warranty ID
- The refund event details from Event Source
- Confirmation that the refund was not legitimate (cross-reference with Grass order data)

**Oncall engineer** must go into the DDB Event Source table and re-activate the EW by editing the refund event.

---

#### Stop Conditions

Escalate if:
- Order data cannot be found
- Multiple EWs are affected for the same customer
- Refund appears legitimate after checking Grass

</details>

---

<details>
<summary>

### 1.6. SOP: G2S2 Extended Warranty Configuration Fallback

</summary>


#### Applicability

**Use this SOP when:**
- Ticket mentions G2S2EWConfigGlobalDefaultFallback error
- Extended warranty purchase fails with configuration error
- System falls back to global default configuration

**DO NOT use if:**
- Issue is about limited warranty (not extended warranty)
- Error is not related to G2S2 configuration

#### Prerequisites

- Ticket creation timestamp
- Marketplace ID (to determine AWS region)
- ASIN from the error

---

#### Procedure

##### Step 1: Search CloudWatch for Error

**Tool:** `CloudWatchLogsTool.searchLogs`
```json
{
  "logGroup": "WSAMainLogs",
  "query": "fields @timestamp, @message | filter @message like 'G2S2EWConfigGlobalDefaultFallback' | sort @timestamp desc",
  "startTime": "<ticket_time_minus_30min>",
  "endTime": "<ticket_time_plus_30min>"
}
```

**Expected:** Log entries showing the fallback metric

---

##### Step 2: Extract Request Details

From logs, identify:
- AWS Request ID
- Order ID
- ASIN
- Marketplace ID
- Customer ID

---

##### Step 3: Get Full Request Logs

**Tool:** `CloudWatchLogsTool.searchLogs`
```json
{
  "logGroup": "WSAMainLogs",
  "query": "fields @timestamp, @message | filter @message like '<request-id>' | sort @timestamp asc"
}
```

---

##### Step 4: Identify Root Cause

The G2S2EWConfigGlobalDefaultFallback indicates:
- Missing extended warranty configuration for the ASIN
- System used global default instead of ASIN-specific config
- Configuration needed in G2S2 `klaw_kws_extend_warranty_configs` table

---

##### Step 5: Resolution

**Escalate to Extended Warranty Onboarding POC:**
- Contact: kulsonam@
- Provide: ASIN, Marketplace ID, Order ID
- Request: Add proper configuration in G2S2

---

---

#### Additional Scenario: EW Config Missing Covered Device ASIN

##### When to Use
- Error: "Cannot bind product to warranty due to no replaceable bindings found"
- EW ASIN does not cover the device ASIN in G2S2 config
- Common in JP marketplace

##### Procedure

**Step 1: Get Device ASIN**

```json
{
  "operation": "QUERY_KEY_TABLE_BY_DEVICE",
  "params": { "dsn": "<DSN>" }
}
```

Note the ASIN from the warranty data.

**Step 2: Check EW ASINs for Device**

```json
{
  "operation": "GET_EW_ASINS",
  "params": { "dsn": "<DSN>" }
}
```

If the EW ASIN is not in the list of valid EW ASINs for this device, the G2S2 config is missing the mapping.

**Step 3: Escalate for G2S2 Config Update**

Contact the EW Onboarding POC (kulsonam@) and provide:
- Device ASIN
- EW ASIN
- Marketplace ID
- Device Type

The fix requires uploading a CSV to the `warranty-configuration-lambda-bucket-prod` S3 bucket with the correct ASIN mapping, then running `UpdateWarrantyConfig` via the oncall lambda for the affected warranty.

---

#### Stop Conditions

Escalate if:
- Cannot find error in CloudWatch logs
- Multiple ASINs affected (may indicate broader issue)
- Configuration already exists but still failing

---

#### Region Reference

| Marketplace | Region |
|-------------|--------|
| NA | us-east-1 |
| EU | eu-west-1 |
| FE | us-west-2 |

</details>

---

<details>
<summary>

### 1.7. SOP: Inactive Binding on Expired Warranty

</summary>


#### Applicability

**Use this SOP when:**
- Error: "There is no actively bound limited warranty to the product"
- Customer has active Extended Warranty (EW)
- Limited Warranty (LW) exists but has inactive binding

**DO NOT use if:**
- No warranty exists at all
- Issue is about warranty expiration (not binding)

#### Prerequisites

- Device serial number (DSN)
- Device type

---

#### Procedure

##### Step 1: Get Warranty Information

**Tool:** `WarrantyServicesTool.getWarrantiesByDevice`
```json
{
  "deviceSerialNumber": "<DSN>",
  "includeClaims": true,
  "includeUnboundEW": true,
  "includePreviouslyBoundWarranties": true
}
```

**Look for:**
- Active Extended Warranty
- Expired Limited Warranty with inactive binding

---

##### Step 2: Check Binding Status in DynamoDB

**Tool:** `DynamoDBQueryTool.queryKeyTable`
```json
{
  "warrantyId": "<LIMITED_WARRANTY_ID>",
  "projection": "warrantyData"
}
```

**Check bindings array:**
- `isActive: false` = INACTIVE binding (causes the error)
- `isActive: true` = ACTIVE binding (should work)

---

##### Step 3: Backfill New Limited Warranty

**Tool:** `WarrantyServicesTool.backfillLimitedWarranty`
```json
{
  "deviceSerialNumber": "<DSN>",
  "deviceType": "<DEVICE_TYPE>"
}
```

This creates:
- New LIMITED_WARRANTY with active binding
- Enables GetReplacementOptions to work

---

##### Step 4: Verify Fix

**Tool:** `WarrantyServicesTool.getWarrantiesByDevice`
```json
{
  "deviceSerialNumber": "<DSN>",
  "includeClaims": true
}
```

**Verify:**
- New warranty exists with active binding
- Replacement options now available

---

#### Key Concepts

**Warranty Validity vs Binding Activity:**
- `warrantyInvalid: false` = warranty is VALID (can be expired but valid)
- `isActive: true` on binding = binding is ACTIVE

**Default Customer ID:**
- `A23ZP02F085DFQ` = system placeholder, NOT a conflict

---

#### Stop Conditions

Escalate if:
- Backfill fails
- Multiple conflicting warranties exist
- Issue persists after backfill

---

#### Region Reference

| Marketplace | Region |
|-------------|--------|
| NA | us-east-1 |
| EU | eu-west-1 |
| FE | us-west-2 |

</details>

---

<details>
<summary>

### 1.8. SOP: KDSS Order Identification Issues

</summary>


#### Applicability

**Use this SOP when:**
- Error: "Exception calling WSA.BackfillLimitedWarrantyV2 for request"
- Error: "KDSS cannot identify an order for deviceSerialNumber"
- Warranty lookup returns empty list

**DO NOT use if:**
- Warranty exists but has other issues
- Error message is different

#### Prerequisites

- Device serial number (DSN)
- Device type
- Ticket creation timestamp

---

#### Procedure

##### Step 1: Verify Empty Warranty List

**Tool:** `WarrantyServicesTool.getWarrantiesByDevice`
```json
{
  "deviceSerialNumber": "<DSN>",
  "includeClaims": true
}
```

**Expected:** Empty warranty list `{ "warrantyList": [] }`

---

##### Step 2: Confirm KDSS Error

**Tool:** `WarrantyServicesTool.getWarrantyClaimCode`
```json
{
  "deviceSerialNumber": "<DSN>"
}
```

**Expected:** Exception with "KDSS cannot identify an order" message

---

##### Step 3: Search CloudWatch for Confirmation

**Tool:** `CloudWatchLogsTool.searchLogs`
```json
{
  "logGroup": "WSAMainLogs",
  "query": "fields @timestamp, @message | filter @message like 'KDSS cannot identify an order for deviceSerialNumber: [<DSN>]' | sort @timestamp desc",
  "startTime": "<ticket_time_minus_30min>",
  "endTime": "<ticket_time_plus_30min>"
}
```

---

##### Step 4: Reassign to KDSS Team

**CTI Path:** Digital Media Technology > Kindle Device Sales > KindleDeviceSalesService

**Include in reassignment:**
- Device Serial Number
- Device Type
- CloudWatch error message
- Request: Fulfill device in KDSS system

---

#### Resolution

Once KDSS fulfills the device:
- System automatically creates warranty
- No further WSA action needed

---

#### Advanced: Manual KDSS Fulfillment (If KDSS Cannot Fulfill)

If KDSS cannot fulfill the device through normal channels, an oncall engineer can manually construct and send a KDSS payload:

**Step 1: Get Device Shipments**

```json
{
  "operation": "GET_DEVICE_SHIPMENTS",
  "params": { "dsn": "<DSN>" }
}
```

This returns shipment info which usually contains test order data that KDSS did not persist as a real order.

**Step 2: Construct KDSS Payload**

Using the shipment data, the oncall engineer constructs a payload for the `KDSSFulfillmentEventsQueue`:

```json
{
  "KDSSPayload": {
    "deviceSerialNumber": "<DSN>",
    "deviceType": "<DEVICE_TYPE>",
    "orderId": "<ORDER_ID>",
    "orderItemId": "<ORDER_ITEM_ID>",
    "orderLineItemId": "<ORDER_LINE_ITEM_ID>",
    "orderUnitId": "<ORDER_UNIT_ID>",
    "orderInstance": 0,
    "marketplaceId": "<MARKETPLACE_ID>",
    "warrantyId": "<WARRANTY_ID>",
    "customerId": "<CUSTOMER_ID>",
    "asin": "<ASIN>"
  }
}
```

**Step 3: Send and Verify**

Oncall engineer sends the payload to the SQS queue in the WSA AWS account. Wait 1-2 minutes, then verify:

```json
{
  "operation": "GET_WARRANTIES_BY_DEVICE",
  "params": { "dsn": "<DSN>" }
}
```

A limited warranty should now appear.

---

#### Stop Conditions

Escalate if:
- Error message is different than expected
- KDSS reports device already fulfilled
- Issue persists after KDSS action

---

#### Region Reference

| Marketplace | Region |
|-------------|--------|
| NA | us-east-1 |
| EU | eu-west-1 |
| FE | us-west-2 |

</details>

---

<details>
<summary>

### 1.9. SOP: Warranty Not Bound to Device After Replacement — "Already Been Replaced by a Different Device" (KRIS `IsBundled` gap)

</summary>


#### Applicability

**Use this SOP when a customer received a warranty replacement device, but the warranty did not move to it:**
- CS reports **"Warranty Not Bound to Device"** or **"Error While Creating Device Replacement"** for a device the customer received **as a replacement**.
- The AC3 / CSC error is one of:
  - `WarrantyReplacementAlreadyProcessedException: … has no eligible warranty claim options. A Claim has been registered and it has already been replaced by: [Order …, AmazonDeviceProduct … DeviceSerialNumber - <OTHER_DSN>]`
  - `DependencyFailureException: … Check if this device [<DSN>] has already been replaced by a different device.`
  - `AccessDeniedException for query orderInformationForDevice … Please restart the workflow.`
- `GET_WARRANTY_CLAIM_CODE` on the **replacement DSN** returns a **500** *"…already been replaced by a different device"* (or a **409** *"…already been replaced by [order/DSN]"* when a prior-owner refurb chain also references the DSN).
- The **replacement device the customer holds has no active warranty** (`GET_WARRANTIES_BY_DEVICE` empty, or only an **invalidated** prior-owner warranty).
- The customer's warranty is still bound to the **original / prior-chain** device: its **active** binding holds the **replacement order** but a **stale product DSN** that is **not** the replacement DSN.

**Scope:** This affects a broad and growing set of device families whose bundled-base-unit classification moved from WSA's hardcoded list to KRIS (KRL-30482 / KRLFRI-97). **Do not rely on a fixed device-type list — match on the symptoms above, not the device type.**

**DO NOT use if:**
- The replacement device already has an **active** warranty (nothing stranded).
- The warranty is genuinely **dormant** with no replacement claim → `astro-dormant-warranty-revival`.
- A mid-chain replacement claim was **cancelled** and coverage correctly reverted to a prior device → `replacement-chain-already-claimed`.
- The replacement device has an **active** warranty owned by a **real, different customer** (true cross-customer refurb) → **STOP, escalate**. This exclusion does **not** apply to: a prior owner's *invalidated/expired* warranty (a refurb artifact), **or** a warranty owned by **`A23ZP02F085DFQ`** — the **encrypted-zero default owner** that owns large numbers of backfilled / refurb / factory warranties and is **not** a real customer. **Never query by `A23ZP02F085DFQ`** (default-owner → full-table scan / RCU spike).

---

#### Key Concept

On a replacement for a bundled-base-unit family, `Warranty.acceptReplacementProductFromOrder` only swaps the replacement product onto the active binding when the products classify as **bundled base units**. KRIS `isBundledBaseDevice` now returns `false` for types that should be bundled (classification moved off WSA's hardcoded list to KRIS ~2026-07-30), so the swap is skipped: the binding keeps the **replacement order** but the **stale (original/prior-chain) product DSN**. The device the customer actually holds ends up with no warranty. This is the "silent" branch — it is frequently **not** logged as a 5XX.

---

#### Detection (read-only — do this before mutating)

1. `GET_WARRANTIES_BY_DEVICE { "dsn": "<REPLACEMENT_DSN>" }` → **empty**, or only a prior-owner warranty with `invalidated: true`.
2. `GET_WARRANTY_CLAIM_CODE { "dsn": "<REPLACEMENT_DSN>", "deviceType": "<DEVICE_TYPE>" }` → **500** "…already been replaced by a different device" (or **409** referencing a prior order/DSN).
3. `GET_DEVICE_SHIPMENTS { "dsn": "<REPLACEMENT_DSN>" }` → confirm which **order** fulfilled the replacement device (most-recent non-RCH/OBA order).
4. Locate the stranded warranty and read the **KeyTable (source of truth — the MV can be stale/misleading)**. Get the `warrantyId` with either of these operations:
```json
{ "operation": "QUERY_KEY_TABLE_BY_DEVICE", "params": { "dsn": "<ORIGINAL_OR_STALE_DSN>", "deviceType": "<DEVICE_TYPE>" } }
```
```json
{ "operation": "QUERY_KEY_TABLE_BY_ORDER", "params": { "orderId": "<REPLACEMENT_ORDER>" } }
```
   then read the full record and inspect its bindings:
```json
{ "operation": "QUERY_KEY_TABLE", "params": { "warrantyId": "<WARRANTY_ID>" } }
```
   Confirm the **active** binding (`isActive: true`) holds the **replacement order** (from step 3) **and** a **product DSN ≠ the replacement DSN**, `invalidated: false`, and the `owner` is the **ticket customer**. Record: `WARRANTY_ID`, the active `bindingId`, the stale product DSN, the replacement order, and the owner customerId (for the post-check).

> The stale product DSN is whatever product currently sits on the active binding — usually the original device, but in a multi-replacement chain it is the **previous** device in the chain (not necessarily the very first).

---

#### Procedure — Device-scoped Unbind (stale product) + Backfill

> ⚠️ Cross-device warranty mutation on production data. **Gate the mutation steps (1 and 3) behind oncall/human approval.** Read the KeyTable first and verify after every step.

**Step 1: Device-scoped unbind of the STALE product** (removes only the product; leaves the order bound)
```json
{ "operation": "UNBIND", "params": { "unbindType": "DEVICE", "dsn": "<STALE_DSN>", "deviceType": "<DEVICE_TYPE>", "warrantyId": "<WARRANTY_ID>" } }
```
Must be `unbindType=DEVICE` with the **stale** DSN. Do NOT unbind the ORDER or do a whole-warranty unbind — dropping the order binding mints a brand-new warranty and loses the claim linkage.

**Step 2: Verify (read-only)** — `QUERY_KEY_TABLE { "warrantyId": "<WARRANTY_ID>" }`. On the active binding (`bindingId` from Detection) confirm it now has **no product entity** but **still lists the replacement order**, and `invalidated` is `false`. **Abort and escalate if the order came off the binding — do NOT backfill.**

**Step 3: Backfill the REAL replacement device** (fulfillment binds it via the empty-slot replacement path — no KRIS check)
```json
{ "operation": "BACKFILL_LIMITED_WARRANTY", "params": { "dsn": "<REPLACEMENT_DSN>", "deviceType": "<DEVICE_TYPE>" } }
```

**Step 4: Verify**
```json
{ "operation": "GET_WARRANTIES_BY_DEVICE", "params": { "dsn": "<REPLACEMENT_DSN>" } }
```
Confirm: warranty active, `associatedDevice = <REPLACEMENT_DSN>`, **owner unchanged**, **claim history intact**; then `GET_WARRANTY_CLAIM_CODE` returns an eligible code (no 500/409).

**Step 5: Resolve** — post a resolution comment (issue, root cause = KRIS `isBundled` gap, actions, verified outcome) and tell CS to re-run the replacement against the replacement DSN in AC3. If CS still sees stale data, force a resync with `REDRIVE_WARRANTY_TO_MV`.

---

#### Why it is safe
- `updateOwner(null)` is a no-op → owner preserved despite backfill's null fulfillment customer.
- `ProcessFulfillment` updates the **existing** warranty (claim preserved); it does not invalidate or mint a new one.
- The unbind commits last → a mismatch throws earlier with no partial mutation (fail-safe).

#### Do NOT
- `INVALIDATE_BINDING` + create a new binding, or `INVALIDATE_WARRANTY` then backfill — destroys the customer's warranty + claim history. (Prior AI reports have wrongly recommended this — reject it.)
- `TRANSFER_LIMITED_WARRANTY` / `TRANSFER_LIMITED_WARRANTY_FOR_CANCELED_CLAIM` — wrong direction; only moves a warranty back to the claiming device.
- Plain backfill **without** unbinding first — no-ops, because the order already has a warranty with a (stale) product.
- Unbind the **order** or the replacement DSN — only the stale product DSN.

#### Stop Conditions
Escalate if:
- The replacement device has an **active** warranty owned by a **real, different customer** — i.e. **not** the encrypted-zero default owner `A23ZP02F085DFQ`, and **not** merely an invalidated prior-owner artifact (true cross-customer refurb).
- The active binding does **not** hold the replacement order, or `UNBIND` / `BACKFILL_LIMITED_WARRANTY` errors, or the warranty does not rebind (durable fix is the KRIS classification correction — KRL-30482 / KRLFRI-97 — after which a fulfillment redrive self-heals).
- Multiple claims are stuck/interleaved on the same warranty.

---

#### Examples (ticket references)

- **P488823070** (JP): active binding held the replacement order + a stale product DSN; device-scoped unbind of the stale product + backfill of the replacement DSN restored coverage, with owner and claim history preserved and an eligible claim code.
- **P493242733** (JP): same signature — unbind of the stale product + backfill of the replacement DSN restored coverage.
- **D511692567** (IT), **D511637452** (UK), **WSA-5269** (DE — multi-replacement chain, where the stale DSN was the *previous* replacement, not the original): all resolved by device-scoped unbind of the stale product + backfill of the replacement DSN.

Related loud/alarm variant: V2307425321 — verify before batching.

</details>

---

<details>
<summary>

### 1.10. SOP: No Replacement Options Error

</summary>


#### Applicability

**Use this SOP when:**
- Error: "No replacement options were returned"
- Customer service cannot create device replacement
- Warranty exists and is valid

**DO NOT use if:**
- No warranty exists (use KDSS SOP)
- Warranty is expired or invalid

#### Prerequisites

- Device serial number (DSN)
- Ticket creation timestamp

---

#### Procedure

##### Step 1: Search CloudWatch for Request

**Tool:** `CloudWatchLogsTool.searchLogs`
```json
{
  "logGroup": "WSAMainLogs",
  "query": "fields @timestamp, @message | filter @message like 'WSA Request: [GetReplacementOptionsRequest' and @message like '<DSN>' | sort @timestamp desc",
  "startTime": "<ticket_time_minus_30min>",
  "endTime": "<ticket_time_plus_30min>"
}
```

Extract the Request ID from results.

---

##### Step 2: Find Filter Logs

**Tool:** `CloudWatchLogsTool.searchLogs`
```json
{
  "logGroup": "WSAMainLogs",
  "query": "fields @timestamp, @message | filter @message like '<REQUEST_ID>' and @message like 'ReplacementOptions Filter' | sort @timestamp asc"
}
```

---

##### Step 3: Analyze Filter Reasons

**Common filter reasons:**
- `AvailabilityFilter`: quantity < 5 (hard-coded threshold)
- `AvailabilityFilter`: quantity = 0
- `PreorderableFilter`: item is preorderable

---

##### Step 4: Reassign to KRIS Team

**CTI Path:** Digital Media Technology > Kindle Reverse Logistics Tech > Kindle Replacement Info Service

**Include in reassignment:**
- Device Serial Number
- Filter reasons from logs
- ASINs that were filtered out
- Request: Update inventory/availability

---

#### Root Cause

WSA filters out replacement options when:
- Inventory quantity < 5 (hard-coded rule)
- Item has zero quantity
- Item is preorderable

This is a KRIS inventory issue, not a WSA issue.

---

#### Additional Scenario: Missing Bundled Component Replacement Option

##### When to Use
- CSA cannot select an accessory/bundled component for replacement
- Component (e.g., remote for Fire TV) is missing from the replacement options list
- Base device replacement options work fine

##### Root Cause

WSA retrieves bundled components from KRIS. If KRIS is missing an accessory in the bundled components configuration, CSAs will not see it as a replaceable component.

##### Resolution

Reassign to KRIS with the Device Type and ASIN, stating which bundled components are missing.

**CTI Path:** Digital Media Technology > Kindle Reverse Logistics Tech > Kindle Replacement Info Service

---

#### Stop Conditions

Escalate if:
- No filter logs found
- Issue is not inventory-related
- KRIS reports inventory is correct

---

#### Region Reference

| Marketplace | Region |
|-------------|--------|
| NA | us-east-1 |
| EU | eu-west-1 |
| FE | us-west-2 |

</details>

---

<details>
<summary>

### 1.11. SOP: OBA Order Binding Issues

</summary>


#### Applicability

**Use this SOP when:**
- Error: "Unable to determine original asin so replacement options cannot be provided"
- Device is bound to OBA (factory test) order
- Order ID starts with "OBA-"

**DO NOT use if:**
- Error is due to null ASIN in events (use unable-to-determine-original-asin SOP)
- No warranty exists (use KDSS SOP)

#### Prerequisites

- Device serial number (DSN)
- Device type

---

#### Procedure

##### Step 1: Get Warranty Information

**Tool:** `WarrantyServicesTool.getWarrantiesByDevice`
```json
{
  "deviceSerialNumber": "<DSN>",
  "includeClaims": true
}
```

Extract the LIMITED_WARRANTY_ID.

---

##### Step 2: Check Order ID in DynamoDB

**Tool:** `DynamoDBQueryTool.queryKeyTable`
```json
{
  "warrantyId": "<LIMITED_WARRANTY_ID>",
  "projection": "warrantyData"
}
```

**Look for OBA order:**
```json
"coveredProduct": {
  "coveredProductEntityReferences": [{
    "@type": "AmazonDeviceOrder",
    "orderId": "OBA-12345678"  // ← OBA prefix = factory test order
  }]
}
```

---

##### Step 3: Try Approach 1 - Update Configuration

**Tool:** `WarrantyServicesTool.updateWarrantyConfiguration`
```json
{
  "warrantyId": "<LIMITED_WARRANTY_ID>",
  "fetchAsin": true
}
```

---

##### Step 4: Verify Fix

**Tool:** `DynamoDBQueryTool.queryKeyTable`
```json
{
  "warrantyId": "<LIMITED_WARRANTY_ID>",
  "projection": "warrantyData"
}
```

If ASIN is now populated, issue is resolved.

---

##### Step 5: If Approach 1 Fails - Invalidate and Recreate

**Tool:** `WarrantyServicesTool.invalidateWarranty`
```json
{
  "warrantyId": "<LIMITED_WARRANTY_ID>"
}
```

**Then:**

**Tool:** `WarrantyServicesTool.backfillLimitedWarranty`
```json
{
  "deviceSerialNumber": "<DSN>",
  "deviceType": "<DEVICE_TYPE>"
}
```

---

##### Step 6: If Still OBA - Reassign to KDSS

**CTI Path:** Digital Media Technology > Kindle Device Sales > KindleDeviceSalesService

**Include:**
- Device Serial Number
- Explanation: Device bound to OBA order
- Request: Fulfill device with proper order

---

#### Stop Conditions

Escalate if:
- Update configuration fails
- Backfill still creates OBA binding
- KDSS reports no valid order exists

---

#### Region Reference

| Marketplace | Region |
|-------------|--------|
| NA | us-east-1 |
| EU | eu-west-1 |
| FE | us-west-2 |

</details>

---

<details>
<summary>

### 1.12. SOP: Order-Level Replacement and Refund Block Issues

</summary>


#### Applicability

**Use this SOP when:**
- CS reports "WSA is blocking" order-level returns/refunds/replacements
- Error mentions "Return window is blocked by warranty service request"
- CS claims warranty is preventing refund

**DO NOT use if:**
- Issue is actually about warranty claims
- Device-level replacement (not order-level)

#### Critical Understanding

**WSA does NOT and CANNOT block order-level operations:**
- WSA has NO influence on order-level replacements
- WSA NEVER blocks refunds
- Order-level operations bypass WSA completely

When CS reports "WSA is blocking" an order-level operation, this is ALWAYS a misdiagnosis.

---

#### Procedure

##### Step 1: Verify Warranty Status

**Tool:** `WarrantyServicesTool.getWarrantiesByDevice`
```json
{
  "deviceSerialNumber": "<DSN>",
  "includeClaims": true,
  "includeUnboundEW": true,
  "includePreviouslyBoundWarranties": true
}
```

Document:
- Warranty IDs
- Claim history (active/cancelled)
- Binding status
- Expiration dates

---

##### Step 2: Provide Warranty Status to CS

**What WSA CAN do:**
- Provide warranty status information
- Unbind warranties (if requested)
- Cancel warranty claims (if needed)
- Provide claim history

**What WSA CANNOT do:**
- Unblock order-level return windows
- Enable refund options
- Override order-level replacement rules

---

##### Step 3: Direct CS to Proper Escalation

**Response to CS:**
```
The warranty information has been reviewed. WSA does not control order-level 
return/refund operations. Please escalate to your CS lead or the appropriate 
team to resolve the order-level blocking issue.

Warranty Status for Reference:
- Warranty ID: [ID]
- Claim Status: [Active/Cancelled/None]
- [Additional relevant warranty details]
```

---

#### Key Points

- WSA = Warranty management system ONLY
- Order-level operations are handled by OTHER systems
- "Warranty blocking refund" is ALWAYS a misdiagnosis
- CS should escalate to their lead for order-level issues

---

#### Alternative Solutions for CS

1. Manual override of return restrictions
2. Process concession/promotional credit
3. Escalate to appropriate team for system-level investigation

---

#### Stop Conditions

This SOP is informational only. WSA cannot resolve order-level blocking issues.

If CS insists WSA is the cause:
- Provide warranty status documentation
- Reiterate that WSA does not control order-level operations
- Recommend CS escalate to their lead

</details>

---

<details>
<summary>

### 1.13. SOP: Order Reassignment Issues

</summary>


#### Applicability

**Use this SOP when:**
- Device needs to be reassigned to a different order
- Incorrect order association during fulfillment
- Customer service adjustment requires order change

**DO NOT use if:**
- Issue is about warranty status (not order)
- Device has no existing warranty

#### Prerequisites

- Device serial number (DSN)
- Current order ID
- Proposed (correct) order ID

---

#### Procedure

##### Step 1: Check Device Shipments

**Tool:** `WarrantyServicesTool.getDeviceShipments`
```json
{
  "deviceSerialNumber": "<DSN>"
}
```

**Check if proposed order exists in shipments.**

---

##### Step 2A: If Proposed Order EXISTS in Shipments

**Cancel existing warranty:**

**Tool:** `WarrantyServicesTool.invalidateWarranty`
```json
{
  "warrantyId": "<CURRENT_WARRANTY_ID>"
}
```

**Backfill new warranty:**

**Tool:** `WarrantyServicesTool.backfillLimitedWarranty`
```json
{
  "deviceSerialNumber": "<DSN>",
  "deviceType": "<DEVICE_TYPE>"
}
```

**Verify new warranty:**

**Tool:** `WarrantyServicesTool.getWarrantiesByDevice`
```json
{
  "deviceSerialNumber": "<DSN>",
  "includeClaims": true
}
```

---

##### Step 2B: If Proposed Order DOES NOT EXIST in Shipments

**Reassign ticket to KDSS:**

**CTI Path:** Digital Media Technology > Kindle Device Sales > KindleDeviceSalesService

**Include:**
- Device Serial Number
- Current Order ID
- Proposed Order ID
- Request: Fulfill device with proposed order

Once KDSS completes fulfillment, system automatically creates warranty under new order.

---

#### Important Notes

- Do NOT include sensitive customer information in ticket comments
- Do NOT mention RCH (replacement) orders in comments
- Keep ticket comments concise

---

#### Stop Conditions

Escalate if:
- Backfill fails after invalidation
- KDSS cannot fulfill with proposed order
- Multiple conflicting orders exist

---

#### Region Reference

| Marketplace | Region |
|-------------|--------|
| NA | us-east-1 |
| EU | eu-west-1 |
| FE | us-west-2 |

</details>

---

<details>
<summary>

### 1.14. SOP: Privacy Compliance DLQ Issues

</summary>


#### Applicability

**Use this SOP when:**
- PrivacyComplianceEventHandlerContainerLambda DLQ alarm
- Error: "Invalid retention days... Retention days cannot be negative"
- GDPR deletion request processing failure

**DO NOT use if:**
- Different Lambda or DLQ
- Error is not about retention days

#### Prerequisites

- Alarm timestamp
- Request ID from logs

---

#### Procedure

##### Step 1: Search for Exception

**Tool:** `CloudWatchLogsTool.searchLogs`
```json
{
  "logGroup": "/aws/lambda/PrivacyComplianceEventHandlerContainerLambda",
  "query": "fields @timestamp, @message | filter @message like 'Exception while handling Boomerang request' | sort @timestamp desc | limit 20",
  "startTime": "<alarm_start>",
  "endTime": "<alarm_end>"
}
```

Extract the `requestId` (format: `SANDFIRE-WORKFLOW-[UUID]`).

---

##### Step 2: Get Request Details

**Tool:** `CloudWatchLogsTool.searchLogs`
```json
{
  "logGroup": "/aws/lambda/PrivacyComplianceEventHandlerContainerLambda",
  "query": "fields @timestamp, @message | filter @message like '<REQUEST_ID>' | sort @timestamp desc | limit 20"
}
```

Extract:
- Customer ID
- Dataset (usually `Kindle.DeviceWarrantyData`)
- Delete Until Time
- Warranty ID (if present)

---

##### Step 3: Query All 3 DynamoDB Tables

**EventSource Table:**

**Tool:** `DynamoDBQueryTool.queryEventSource`
```json
{
  "warrantyId": "<WARRANTY_ID>",
  "limit": 20
}
```

Look for `expirationDate` in `WarrantyBackfilled` events.

**KeyTable:**

**Tool:** `DynamoDBQueryTool.queryKeyTableByEntityId`
```json
{
  "entityId": "<CUSTOMER_ID>",
  "limit": 20
}
```

**DormantWarranties Table:**

**Tool:** `DynamoDBQueryTool.getDormantWarranty`
```json
{
  "warrantyId": "<WARRANTY_ID>"
}
```

---

##### Step 4: Calculate Retention Period

1. **Warranty Expiration Date:** From EventSource analysis
2. **Retention Period:** 10 years from warranty expiration
3. **Expected Deletion Date:** Expiration + 10 years
4. **Current Date:** When request was made

**If current date > expected deletion date:**
- Data should have been auto-deleted but wasn't
- Causes negative retention days calculation

---

##### Step 5: Manual Deletion Required

**REQUIRES HUMAN ENGINEER EXECUTION**

Provide verification summary:
- Warranty ID
- Expiration Date
- Calculated retention period
- Confirmation data is overdue for deletion

Engineer manually deletes the data, then re-drives DLQ.

---

#### Stop Conditions

Escalate if:
- Cannot find warranty expiration date
- Data is NOT overdue for deletion
- Multiple warranties affected

---

#### Important Notes

- Data deletion is IRREVERSIBLE
- Ensure all verifications complete before deletion
- This ensures GDPR compliance

---

#### Region Reference

| Marketplace | Region |
|-------------|--------|
| NA | us-east-1 |
| EU | eu-west-1 |
| FE | us-west-2 |

</details>

---

<details>
<summary>

### 1.15. SOP: "Already Claimed" / "Not Bound" After a Mid-Chain Claim Cancellation

</summary>


#### Applicability

**Use this SOP when:**
- Device went through **multiple replacements** (original → Repl 1 → Repl 2 …) and CS now gets **"already claimed warranty"** or **"Warranty Not Bound to Device"** when trying a new replacement.
- Somewhere in the chain a replacement claim was **cancelled** (e.g. wrong-color / wrong device returned), and the warranty appears to be sitting on a **returned or older** device in the chain.
- Decision path: `... > Replacement Workflow Error > Device Replacement Error > Warranty Not Bound to Device`.

**DO NOT use if:**
- Warranty is expired — expired coverage correctly yields discount-only options (no defect).
- EW is bound at **order level with no device** after a replacement (use `warranty-binding` Issue Type 1 / `oba-order-binding`).
- EW ASIN does not cover the device (use `warranty-type-mismatch`).
- Device has no fulfillment record at all (use `kdss-order-identification`).
- **No claim was cancelled** — the replacement device simply has **no warranty** and the customer's active binding holds the **replacement order + a stale product DSN** (warranty stranded on the original/prior device). That is the KRIS `IsBundled` gap, not a mid-chain cancellation → use [`kris-isbundled-orphaned-replacement`](../kris-isbundled-orphaned-replacement/README.md).

---

#### Key Concept: Cancelling a Claim Reverts Coverage to the Prior Device

A replacement claim **transfers** the warranty from its claim device to the replacement device. **Cancelling that claim reverses the transfer** — coverage snaps back to the *prior* device in the chain. This is **correct, expected behavior**, not a "stuck" binding.

So after a cancelled mid-chain claim, the warranty legitimately lives on the **last device produced by a non-cancelled claim** — which may be a device the customer has already **returned**. The customer is usually holding a *different* device (the cancelled/wrong one), so CS's claim attempt against the device-in-hand fails with "already replaced" — even though the warranty itself is healthy.

**The block is almost always on the wrong DSN, not a broken binding.** Confirm which DSN is claimable *before* mutating anything.

---

#### Procedure

##### Step 1: Map the Full Replacement Chain

For the DSN on the ticket, run:
```json
{ "operation": "GET_WARRANTIES_BY_DEVICE", "params": { "dsn": "<TICKET_DSN>" } }
```
From `claimHistory`, list every claim chronologically with: claim device → replacement device, `isCancelled`, and `claimReasonCode`. Identify the current `associatedDevice` (where the warranty is bound now).

##### Step 2: Probe EVERY DSN in the Chain (read-only, no mutation)

For each DSN in the chain (original + every replacement), run:
```json
{ "operation": "GET_WARRANTY_CLAIM_CODE", "params": { "deviceSerialNumber": "<DSN>", "customerId": "<CUST_ID>" } }
```
`GetWarrantyClaimCode` **does not create a claim** — it returns the eligibility token CS fetches *before* raising one, so it safely reproduces exactly what CS sees.

##### Step 3: Interpret

- **Valid `warrantyClaimCode` returned (eligible, RETURNABLE)** → this DSN is **claimable**. This is the device CS must claim against.
- **409 "…has already been replaced by \[order/DSN\]"** → this DSN was consumed by a non-cancelled claim; not claimable.
- **500 "…has already been replaced by a different device"** → tangled/replaced unit (often the cancelled-claim output); not claimable.

Typically **exactly one** DSN returns a valid code — the last device produced by a live (non-cancelled) claim.

##### Step 4: Route CS to the Claimable DSN (usually NO WSA mutation)

If a claimable DSN exists, **no binding/claim surgery is needed.** Instruct CS (CORRESPONDENCE) to raise the replacement **against that DSN** in AC3 — use `AE_FREE_UPGRADE_WITH_EXCEPTION` for a color/model swap — and RMA the wrong device. The warranty auto-transfers to the new unit on fulfillment.

##### Step 5: Resolve (do not reassign)

Per team precedent, **Resolve** the ticket (`closureCode: Successful`) with a resolution note; leave the assignee as the WSA oncall alias. Do **not** reassign to a CS resolver group — the requester (CS agent) is notified via SIM + the ZTI ingestion watcher and re-attempts in AC3.

---

#### Do NOT

- ❌ **Do NOT cancel the legitimate active upstream claim** (the one that produced the current bound device) to "transfer the warranty back to the original device." That reverses a real replacement's history and is unnecessary — the `TRANSFER_LIMITED_WARRANTY_FOR_CANCELED_CLAIM` / warranty-binding Issue Type 4 path is **only** for when the customer actually wants to keep the **original** device.
- ❌ **Do NOT bind the warranty to the returned/wrong device the customer is holding.** Once its claim is cancelled there is nothing to bind against, and it is being returned anyway.
- ❌ **Do NOT trust a prior AI-agent "cancel + transfer back" recommendation** without running the Step 2 probe first.

---

#### Decision Matrix

| Probe result across chain | Action |
|---|---|
| Exactly one DSN claimable | Route CS to that DSN; resolve. No mutation. |
| No DSN claimable | Investigate stuck/order-level binding (`warranty-binding`); escalate. |
| Claimable DSN belongs to a **different customer** | Stop — do not proceed. |
| Warranty expired | No defect; discount-only is correct. Resolve as expected behavior. |

---

#### Stop Conditions

Escalate / stop if:
- No DSN in the chain is claimable (possible stuck order-level binding).
- A chain DSN carries a warranty for a **different customer** (refurb DSNs often carry an expired prior-owner warranty — informational, but any binding op MUST target the correct `Warranty-<id>` explicitly).
- Claims are interleaved across multiple warranties, or a tool returns an unexpected error.

---

#### Example (anonymized)

> Identifiers below are **placeholders**. Never commit real customer IDs, DSNs, order IDs, or warranty/claim IDs into an SOP.

Kindle Scribe, cust `<CUSTOMER_A>`, `Warranty-XXXX` (in-term):
- `Claim-AAAA` (SCREEN_CRACK, free) — original `<ORIGINAL_DSN>` → Repl 1 `<REPL_1_DSN>`. **Active.**
- `Claim-BBBB` (SYS_FROZEN, free) — Repl 1 → Repl 2 `<REPL_2_DSN>` (**wrong color**). **Cancelled by CS** → coverage reverted to Repl 1.

Probe results:
- Repl 1 `<REPL_1_DSN>` → ✅ valid claim code (eligible, RETURNABLE).
- Original `<ORIGINAL_DSN>` → ❌ 409 already replaced by Repl 1.
- Repl 2 `<REPL_2_DSN>` → ❌ 500 already replaced by a different device.

`GetDeviceShipments` showed both replacements are refurb stock (prior RCH/OBA shipments); Repl 1's expired foreign warranty (a *different* customer `<CUSTOMER_B>`) is a refurb artifact, not fraud.

**Resolution:** No WSA mutation. Routed CS to raise the correct-color replacement against Repl 1 `<REPL_1_DSN>` and RMA the wrong-color Repl 2 `<REPL_2_DSN>`; resolved `Successful`. A prior AI report had recommended cancelling the legitimate active claim (`Claim-AAAA`) + transferring back to the original device — rejected as wrong (reverses a legitimate claim) and unnecessary (Repl 1 was already claimable).

</details>

---

<details>
<summary>

### 1.16. SOP: Unable to Determine Original ASIN

</summary>


#### Applicability

**Use this SOP when:**
- Error: "Unable to determine original asin so replacement options cannot be provided"
- Error code includes [kla:213aabff]
- BoundEntityUpdated events have `"asin":null`

**DO NOT use if:**
- Device bound to OBA order (use oba-order-binding SOP)
- No warranty exists (use KDSS SOP)

#### Prerequisites

- Device serial number (DSN)
- Warranty ID

---

#### Procedure

##### Step 1: Get Warranty Information

**Tool:** `WarrantyServicesTool.getWarrantiesByDevice`
```json
{
  "deviceSerialNumber": "<DSN>",
  "includeClaims": true,
  "includeUnboundEW": true,
  "includePreviouslyBoundWarranties": true
}
```

Extract the `warrantyId`.

**CRITICAL:** If Customer ID is `A23ZP02F085DFQ`, avoid customer ID-based queries.

---

##### Step 2: Query EventSource Table

**Tool:** `DynamoDBQueryTool.queryEventSource`
```json
{
  "warrantyId": "<WARRANTY_ID>"
}
```

**Look for pattern:**
1. `AmazonDeviceProductBoundToWarranty` - Should have correct ASIN
2. `BoundEntityUpdated` - Shows `"asin":null` (the problem)

---

##### Step 3: Verify Problem Pattern

**Expected pattern:**
- `AmazonDeviceProductBoundToWarranty`: `"asin":"B0XXXXXXXX"` ✓
- `BoundEntityUpdated`: `"asin":null` ✗

**STOP if pattern not found** - different issue, inform engineer.

---

##### Step 4: Extract Correct ASIN

From `AmazonDeviceProductBoundToWarranty` event, extract the correct ASIN.

Optional verification:

**Tool:** `WarrantyServicesTool.getDeviceShipments`
```json
{
  "dsn": "<DSN>",
  "deviceType": "<DEVICE_TYPE>"
}
```

---

##### Step 5: Manual Fix Required

**REQUIRES HUMAN ENGINEER EXECUTION**

Provide information for manual EventSource update:
- Warranty ID
- Event IDs of BoundEntityUpdated events with null ASIN
- Correct ASIN from AmazonDeviceProductBoundToWarranty
- Region
- Table: EventSource

---

##### Step 6: Post-Fix Verification

**Tool:** `DynamoDBQueryTool.queryEventSource`
```json
{
  "warrantyId": "<WARRANTY_ID>",
  "filterEventName": "BoundEntityUpdated"
}
```

**Verify:** All BoundEntityUpdated events show correct ASIN (not null).

**ONLY post resolution after successful verification.**

---

#### Root Cause

Legacy bug caused ASIN overrides on device FRO events. Bug is fixed, but old data exists with null ASINs.

---

#### Stop Conditions

Escalate if:
- Pattern not found in EventSource
- Multiple conflicting ASINs exist
- Manual update fails

---

#### Region Reference

| Marketplace | Region |
|-------------|--------|
| NA | us-east-1 |
| EU | eu-west-1 |
| FE | us-west-2 |

</details>

---

<details>
<summary>

### 1.17. SOP: Warranty Binding Issues

</summary>


#### Applicability

**Use this SOP when:**
- Extended warranty won't bind to device
- Warranty stuck on previous/wrong device
- Duplicate warranty bindings exist
- "Cannot bind" errors reported

---

#### Issue Type 1: Extended Warranty Stuck on Previous Device

##### When to Use
- Extended warranty bound to old device after replacement
- Error: "Cannot bind to Warranty: [ID] because another binding exists"

##### Procedure

**Step 1: Verify Ownership**

Query BOTH devices using the API operation (preferred - returns CS view):
```json
{
  "operation": "GET_WARRANTIES_BY_DEVICE",
  "params": { "dsn": "<OLD_DSN>" }
}
```
```json
{
  "operation": "GET_WARRANTIES_BY_DEVICE",
  "params": { "dsn": "<NEW_DSN>" }
}
```

Note: deviceType is auto-looked up from DIS if not provided.

Verify:
- Same `customerId` on both devices
- Claim history shows device replacement
- Extended warranty order ID matches device order ID

**If different customers or order IDs don't match:** Escalate

**Step 2: Identify Active Binding**

From old device data, find:
- Extended Warranty ID
- Active binding ID (no `unBindTime`)

**Step 3: Invalidate Current Binding**

**Tool:** `WSAOncallOperationsTool.invalidateBinding`
```json
{
  "warrantyId": "<EW_ID>",
  "bindingId": "<ACTIVE_BINDING_ID>"
}
```

**Step 4: Bind to New Device**

**Tool:** `WSAOncallOperationsTool.bindExtendedWarranty`
```json
{
  "warrantyId": "<EW_ID>",
  "deviceSerialNumber": "<NEW_DSN>",
  "deviceType": "<DEVICE_TYPE>",
  "marketplaceId": "<MARKETPLACE_ID>"
}
```

**Step 5: Verify**

Query new device, confirm:
- EW shows new device as `associatedDevice`
- New binding in `bindingHistory`
- Previous binding has `unBindTime`

---

#### Issue Type 2: Duplicate Actively Bound Warranties

##### When to Use
- Replacement device has two active limited warranties
- One from previous owner, one from current customer

##### Procedure

**Step 1: Query Device**

Use API operation (preferred):
```json
{
  "operation": "GET_WARRANTIES_BY_DEVICE",
  "params": { "dsn": "<DSN>" }
}
```

Identify which warranty belongs to current customer (from ticket).

**Step 2: Invalidate Previous Owner's Warranty**

**Tool:** `WSAOncallOperationsTool.invalidateWarranty`
```json
{ "warrantyId": "<PREVIOUS_OWNER_WARRANTY_ID>" }
```

**Step 3: Verify**

Only one active warranty remains, belonging to current customer.

---

#### Issue Type 3: Extended Warranty Not Compatible with Device Type ("not covered by Warranty ASIN")

##### When to Use
- Error: "Cannot bind to Warranty: [ID] because Product: [AmazonDeviceProduct: DeviceType - X, DeviceSerialNumber - Y] is not covered by Warranty ASIN [ASIN]"

##### Background — stale config snapshot (most common cause)

Extended warranties store a **materialized snapshot** of their covered-devices list
(`coveredDeviceConfigs`, a set of device ASIN ↔ device type pairs) captured at warranty
**creation time**. This snapshot does not auto-update. If the EW ASIN's covered-devices config is
later expanded to add the device's type, warranties created *before* that change keep the old
snapshot, and the bind is rejected even though the **current** ASIN config covers the device.

The CS/oncall bind path matches on **device type only** (not ASIN). So the fix is to confirm the
current config covers the device **type**, then refresh the warranty's snapshot from the current
config — this is not a "force bind" and does not bypass coverage.

##### Procedure

**Step 1: Locate the EW and confirm binding state**

If the EW is not already on the device, find it by customer:
```json
{ "operation": "GET_EXTENDED_WARRANTIES_BY_CUSTOMER", "params": { "customerId": "<CUSTOMER_ID>" } }
```
Note the warranty ID and its ASIN. If there is an active **order-only** binding (bound to order, not
device), invalidate it first (see Issue Type 1, Step 3). If `bindingHistory` is empty, there is
nothing to invalidate.

**Step 2: Confirm the current ASIN config covers the device TYPE**

```json
{ "operation": "GET_EW_ASINS", "params": { "dsn": "<DSN>" } }
```
The EW's ASIN should appear in the returned list — this confirms the live G2S2 config covers this
device. Optionally inspect the stale snapshot to confirm the root cause:
```json
{ "operation": "QUERY_EVENT_SOURCE", "params": { "warrantyId": "<EW_ID>" } }
```
The creation event's `coveredDeviceConfigs` will be missing the device's current device type.

**If the current config does NOT cover the device type → STOP** (see Stop Conditions). Do not refresh
or force the bind — this is a genuine coverage/config question, not a stale snapshot.

**Step 3: Refresh the warranty config snapshot**

Re-pull the current covered-devices list onto the warranty:
```json
{ "operation": "UPDATE_WARRANTY_CONFIGURATION", "params": { "warrantyId": "<EW_ID>", "fetchAsin": true } }
```
This only re-materializes this warranty's own snapshot from the authoritative G2S2 config — it does
**not** alter the shared ASIN config, other warranties, bindings, owner, or dates.

**Step 4: Bind**

```json
{
  "operation": "BIND_EXTENDED_WARRANTY",
  "params": { "warrantyId": "<EW_ID>", "dsn": "<DSN>", "deviceType": "<DEVICE_TYPE>", "marketplaceId": "<MARKETPLACE_ID>" }
}
```

**Step 5: Verify**

```json
{ "operation": "GET_WARRANTIES_BY_DEVICE", "params": { "dsn": "<DSN>" } }
```
Confirm the EW now shows the device as `associatedDevice` with an active binding in `bindingHistory`.

##### Stop Conditions (Issue Type 3)

- **Current config does NOT cover the device type** (the EW ASIN is absent from `GET_EW_ASINS` for the
  DSN): do not refresh or bind. This is a real coverage/config-data question — escalate to the EW
  config POC (**kulsonam@**). Common sub-cases: the plan legitimately shouldn't cover this device, or
  the device-ASIN ↔ device-type mapping / device-type registration is itself wrong.
- **Refresh succeeds but the bind still fails**: escalate with the warranty ID, DSN + device type, and
  the exact error.

##### Example

Ticket V2324936388: EW `Warranty-7d7f7772-...` (ASIN `B0BRR2CQ9S`) would not bind to DSN
`G9V2GR04331100A1` (device type `A8MCGN45KMHDH`). The creation snapshot covered only
`A2CT0VL0UUQ7I3`. `GET_EW_ASINS` confirmed the live config for the device covers `B0BRR2CQ9S`;
`UPDATE_WARRANTY_CONFIGURATION` (`fetchAsin: true`) followed by `BIND_EXTENDED_WARRANTY` succeeded
(`Binding-32f2e221-...`, active through 2028-04-29). Sibling ticket V2323776415 (ASIN `B09MV6RG6N`)
resolved identically. Residual device-type ↔ device-ASIN mapping questions were routed to the EW
config owners (POC kulsonam@).

---

#### Issue Type 4: Transfer Warranty Back After Claim

##### When to Use
- Customer wants to keep original device
- Warranty transferred to replacement during claim

##### Procedure

**Step 1: Check Both Devices**

Query both original and replacement devices using API operation:
```json
{
  "operation": "GET_WARRANTIES_BY_DEVICE",
  "params": { "dsn": "<ORIGINAL_DSN>" }
}
```
```json
{
  "operation": "GET_WARRANTIES_BY_DEVICE",
  "params": { "dsn": "<REPLACEMENT_DSN>" }
}
```

**Step 2: Cancel Claim (if needed)**

**Tool:** `WSAOncallOperationsTool.cancelClaim`
```json
{ "claimId": "<CLAIM_ID>" }
```

**Step 3: Transfer Warranty**

Use the API operation for transferring warranty after canceled claim:
```json
{
  "operation": "TRANSFER_LIMITED_WARRANTY_FOR_CANCELED_CLAIM",
  "params": {
    "warrantyId": "<WARRANTY_ID>",
    "dsn": "<ORIGINAL_DSN>"
  }
}
```

Note: deviceType is auto-looked up from DIS if not provided.

**Step 4: Verify**

Query the original device again to confirm warranty is now bound:
```json
{
  "operation": "GET_WARRANTIES_BY_DEVICE",
  "params": { "dsn": "<ORIGINAL_DSN>" }
}
```

---

#### Decision Matrix

| Scenario | Action |
|----------|--------|
| Same customer, matching orders, claim history | Proceed |
| Same customer, no clear indicators | Escalate |
| Different order IDs | Escalate |
| Different customers | Stop - do not proceed |

---

#### Stop Conditions

Escalate if:
- Devices belong to different customers
- Order IDs don't match
- Tool returns unexpected error
- Verification shows unexpected state

---

#### Ticket Resolution: "Warranty Not Bound to Device" (CS Retry Path)

For "warranty not bound to device" tickets where **no oncall binding operation
is required** — the state is valid and the binding will succeed on a
customer-service retry — resolve the ticket with a note rather than reassigning
it.

##### Procedure

**Step 1:** Confirm no oncall action is needed (device and warranty state are
valid; the binding simply has not been retried).

**Step 2:** Resolve the ticket:
- **closureCode:** `Successful`
- **rootCause:** the applicable transient / CS-retry root cause
- **resolution note:** instruct CS to retry the binding in AC3

**Step 3:** Do **not** reassign the ticket to a CS group or individual. Leave
the assignee as the WSA oncall alias.

##### Why

SIM resolution notifies the requester, and the ZTI watcher forwards the
resolution back to CS/AC3 automatically — so a resolve-with-note reaches CS
without a manual reassignment. D2 ticketing agents pass tickets into the queue
but do not own the resolve; the WSA oncall owns it.

</details>

---

<details>
<summary>

### 1.18. SOP: Warranty Deletion Issues (Old Devices)

</summary>


#### Applicability

**Use this SOP when:**
- Error: "Error occurred while determining warranty claim eligibility codes"
- Error suggests device "has already been replaced by a different device"
- Device is more than 10 years old

**DO NOT use if:**
- Device is less than 10 years old
- Warranty exists but has other issues

#### Prerequisites

- Device serial number (DSN)
- Device type

---

#### Procedure

##### Step 1: Check Device Shipment Date

**Tool:** `WarrantyServicesTool.getDeviceShipments`
```json
{
  "dsn": "<DSN>",
  "deviceType": "<DEVICE_TYPE>"
}
```

**Check:** Was device shipped more than 10 years ago?

---

##### Step 2: Confirm Warranty Deletion Status

**Tool:** `WarrantyServicesTool.backfillLimitedWarranty`
```json
{
  "deviceSerialNumber": "<DSN>",
  "deviceType": "<DEVICE_TYPE>"
}
```

**If response includes:** `"warrantyStatusCode": "WARRANTY_DELETED"`
- Confirms warranty was deleted due to age

---

##### Step 3: Inform Customer Service

**Resolution:** Warranty cannot be recovered.

**Response to CS:**
```
The device warranty has been permanently deleted from the system due to its age 
(over 10 years old). The device is no longer eligible for warranty service.

Device Information:
- Serial Number: [DSN]
- Ship Date: [DATE]
- Status: WARRANTY_DELETED

Alternative options should be discussed with the customer.
```

---

#### Key Points

- Warranties are deleted after 10 years (data retention policy)
- Deleted warranties CANNOT be recovered
- Error message about "replaced by different device" is misleading
- Actual cause is warranty deletion due to age

---

#### Stop Conditions

This SOP is informational. No fix is possible for deleted warranties.

If CS requires further assistance:
- Confirm device age
- Explain data retention policy
- Suggest alternative customer resolution options

</details>

---

<details>
<summary>

### 1.19. SOP: Warranty Type & Configuration Mismatches

</summary>


#### Applicability

**Use this SOP when:**
- Warranty shows as Limited but should be Worry Free
- Claim limit reached (3 claims) but warranty is not expired
- RCH/OBA order has wrong warranty type due to marketplace mismatch
- Error: "Error retrieving EW Warranty Configuration for marketplace"
- CS reports warranty duration is incorrect

**DO NOT use if:**
- Warranty is missing entirely (use kdss-order-identification SOP)
- G2S2 config is missing for an ASIN (use g2s2-config-fallback SOP)
- Warranty dates are wrong on refurbished device (use certified-refurbished SOP)

#### Prerequisites

- Device serial number (DSN)
- Marketplace context from the ticket

---

#### Issue Type 1: Claim Limit Reached

##### When to Use
- Warranty shows Out of Warranty (OOW) but expiration date has not passed
- Customer has made 3 claims on the same limited warranty
- Limited warranties have a hard-coded claim limit of 3

##### Procedure

**Step 1: Verify Warranty State**

```json
{
  "operation": "GET_WARRANTIES_BY_DEVICE",
  "params": { "dsn": "<DSN>" }
}
```

Confirm warranty is not expired but shows OOW. Check claim history — if 3 claims exist, this is the cause.

**Step 2: Inform CS**

The claim limit of 3 is hard-coded for limited warranties (Worry Free warranties have unlimited claims). There is no WSA fix. Direct CS to issue an exception replacement.

**Note:** This is expected behavior, not a bug.

---

#### Issue Type 2: RCH/OBA Order — Wrong Warranty Type (Should Be Worry Free)

##### When to Use
- Device is typically in JP marketplace
- Kids Edition Tablet (KET) or similar device that should have Worry Free warranty
- Warranty shows as Limited with 1-year expiration instead of Worry Free with 2-year
- Order is an offline purchase (RCH or OBA order)

##### Procedure

**Step 1: Verify Current State**

```json
{
  "operation": "GET_WARRANTIES_BY_DEVICE",
  "params": { "dsn": "<DSN>" }
}
```

Confirm warranty type is LIMITED when it should be WORRY_FREE.

**Step 2: Check Order Type**

```json
{
  "operation": "QUERY_KEY_TABLE_BY_DEVICE",
  "params": { "dsn": "<DSN>" }
}
```

Look at the order ID. If it starts with `RCH-` or `OBA-`, this confirms the root cause: KDSS fulfills all offline orders as NA marketplace, so WSA looked up config in NA instead of the correct marketplace (e.g., JP).

**Step 3: Escalate for Marketplace Update**

The fix is to update the warranty configuration using the correct marketplace. Provide the oncall engineer with:
- Warranty ID
- DSN and Device Type
- Correct marketplace ID (e.g., `A1VC38T7YXB528` for JP)

**Oncall engineer** can use WSA Tools to pull up the warranty and select the correct marketplace, which will fetch the Worry Free configuration and update the warranty.

---

#### Issue Type 3: Warranty Type Incorrect (LW vs Worry Free)

##### When to Use
- Device should have Worry Free warranty but shows Limited
- Not an RCH/OBA order (online purchase)
- Configuration may be wrong or ASIN mapping may be incorrect

##### Procedure

**Step 1: Verify Current State**

```json
{
  "operation": "GET_WARRANTIES_BY_DEVICE",
  "params": { "dsn": "<DSN>" }
}
```

**Step 2: Check Event History**

```json
{
  "operation": "QUERY_EVENT_SOURCE",
  "params": { "warrantyId": "<WARRANTY_ID>" }
}
```

Look at the original warranty creation event. Check if the ASIN is correct and if the warranty type was set correctly at creation.

**Step 3: Escalate**

If the ASIN is correct but warranty type is wrong, this is a G2S2 configuration issue. Escalate to the Limited Warranty Onboarding POC (priyalsm@) or Extended Warranty Onboarding POC (kulsonam@) with:
- ASIN
- Marketplace ID
- Current warranty type vs expected warranty type

For limited-warranty config issues, reassign to priyalsm@ using CTI **Digital Media Technology / Kindle Reverse Logistics / Replacement Config Issue** (resolver group **ADRL NPI LRM**).

---

#### Issue Type 4: Error Retrieving EW Config (Wrong Marketplace)

##### When to Use
- Error: "Error retrieving EW Warranty Configuration for marketplace 'X', asin 'Y'"
- Customer has unbound EW purchased in a different marketplace
- CS is accessing CSCentral from a different marketplace than where EW was purchased

##### Procedure

**Step 1: Find the EW**

```json
{
  "operation": "GET_EXTENDED_WARRANTIES_BY_CUSTOMER",
  "params": { "customerId": "<CUSTOMER_ID>" }
}
```

Identify the unbound EW and note its ASIN and the marketplace it was purchased in.

**Step 2: Identify Marketplace Mismatch**

The error occurs because WSA uses the marketplace from the CS request (CSCentral marketplace), not the EW purchase marketplace, when looking up G2S2 config. If the EW was bought in UK but CS is filing from US, the config lookup fails.

**Step 3: Inform CS**

Direct the CS representative to file the claim through the correct CSCentral marketplace — the one where the EW was purchased. This will resolve the config lookup error.

---

#### Stop Conditions

Escalate if:
- Warranty type is wrong and root cause is unclear
- G2S2 configuration needs to be updated
- Multiple devices/customers affected by the same config issue

</details>

---

<details>
<summary>

### 1.20. SOP: WSA Self Replacement Null Fields

</summary>


#### Applicability

**Use this SOP when:**
- Error: "Cannot invoke Currency.getUnit() because ReplacementOption.getListPrice() is null"
- CloudWatch shows replacement option with mostly null fields
- Only `asin`, `costToCustomer`, `isValidOption` are populated

**DO NOT use if:**
- No replacement options at all (use no-replacement-options SOP)
- Error is about ASIN determination (use unable-to-determine-original-asin SOP)

#### Prerequisites

- Device serial number (DSN)
- Selected component ASIN
- Marketplace ID
- Error timestamp

---

#### Procedure

##### Step 1: Search CloudWatch for Error

**Tool:** `CloudWatchLogsTool.searchLogs`
```json
{
  "logGroup": "WSAMainLogs",
  "query": "fields @timestamp, @message | filter @message like 'GetReplacement' and @message like '<SELECTED_COMPONENT_ASIN>' | sort @timestamp desc"
}
```

**Look for log showing:**
- `listPrice=null`
- `offerListingId=null`
- `merchantId=null`
- Only populated: `asin`, `costToCustomer`, `isValidOption`

---

##### Step 2: Confirm Self-Replacement Scenario

This occurs when:
1. KRIS returns no device replacement options
2. Selected component has no deviceType
3. System creates "self replacement option"
4. No offer found for ASIN in marketplace
5. Fields remain null → downstream NPE

---

##### Step 3: Reassign to ADRL Team

**This requires ADRL configuration, not WSA fix.**

**Provide to ADRL:**
- Selected Component ASIN
- Marketplace ID
- Device Type
- Error: Self-replacement option created with null fields
- Root Cause: No KRIS configuration and no offers available
- Required Action: Configure ASIN in KRIS/G2S2 for this marketplace

---

#### Root Cause

Configuration gap in KRIS/G2S2:
- Missing KRIS configuration for the ASIN
- No offers available in the marketplace
- Self-replacement fallback creates incomplete data

---

#### Stop Conditions

Escalate if:
- Error is different than expected
- ADRL reports configuration exists
- Issue affects multiple ASINs

---

#### Region Reference

| Marketplace | Region |
|-------------|--------|
| NA | us-east-1 |
| EU | eu-west-1 |
| FE | us-west-2 |

</details>

---

## 2. Alarms

<details>
<summary>

### 2.1. SOP: 5XX TransferLW for CanceledClaim Alarm

</summary>


#### Applicability

**Use this SOP when:**
- Alarm: `5XXError: TransferLimitedWarrantyForCanceledClaim-prod.*`
- 5XX errors on TransferLimitedWarrantyForCanceledClaim API

**DO NOT use if:**
- 5XX errors on other APIs (use general 5XX alarm investigation)
- Alarm is for BackfillLimitedWarrantyV2 (use kdss-order-identification SOP)

---

#### Procedure

##### Step 1: Check Error Volume and Timing

```json
{
  "operation": "QUERY_CLOUDWATCH_LOGS",
  "params": {
    "queryString": "fields @timestamp, @message | filter @message like /ActivityCleanupInterceptor InvocationException, throwing to client/ | filter @message like /TransferLimitedWarrantyForCanceledClaim/ | stats count(*) as failures by bin(5m) | sort @timestamp desc",
    "startTime": "<alarm_time_minus_2h_epoch>",
    "endTime": "<alarm_time_plus_1h_epoch>"
  }
}
```

##### Step 2: Identify the Failing DSNs

```json
{
  "operation": "QUERY_CLOUDWATCH_LOGS",
  "params": {
    "queryString": "fields @timestamp, @message | filter @message like /does not have an active Claim to cancel to transfer Warranty back to Product:/ | stats count(*) as attempts by @message | sort attempts desc | limit 20",
    "startTime": "<alarm_time_minus_2h_epoch>",
    "endTime": "<alarm_time_plus_1h_epoch>"
  }
}
```

##### Step 3: Analyze Pattern

**CSA Retry Pattern (most common):**
- Same DSN appears repeatedly during the alarm window
- Error: "Warranty: [X] does not have an active Claim to cancel to transfer Warranty back to Product: [X]"
- This means a CSA is trying to cancel an already-canceled claim multiple times

**If same DSN repeats:** This is transient — CSA troubleshooting behavior. No action needed.

**If multiple different DSNs:** Investigate further — may indicate a systemic issue.

##### Step 4: Resolution

**If CSA retry confirmed:**
- Close ticket with explanation: "Logs confirm transient 5XX errors caused by CSA attempting to cancel an already-canceled claim on DSN [X] multiple times during troubleshooting. No systemic issue."

**If not CSA retry:**
- Escalate for deeper investigation

---

#### Stop Conditions

Escalate if:
- Multiple different DSNs are failing
- Error pattern does not match CSA retry behavior
- 5XX errors are ongoing and increasing

</details>

---

<details>
<summary>

### 2.2. SOP: DynamoDB High TPS Alarm Analysis

</summary>


#### Applicability

**Use this SOP when:**
- Ticket references DynamoDB high TPS alarm
- Alarm mentions customerIDIndex TPS spike
- CloudWatch alarm for DDB throttling

**Common Alarm Names:**
- `WSA-DDB-CustomerIDIndex-HighTPS`
- `WarrantyServices-DDB-Throttling`

---

#### Procedure

##### Step 1: Get Alarm Details

**Tool:** `CloudWatchLogsTool.getAlarmState`
```json
{
  "alarmNamePrefix": "WSA-DDB",
  "stateValue": "ALARM"
}
```

Note: Alarm name, trigger time, affected table/index

---

##### Step 2: Query Logs for TPS Source

**Tool:** `CloudWatchLogsTool.queryLogs`
```json
{
  "logGroupName": "/aws/lambda/WarrantyServices-API",
  "queryString": "fields @timestamp, @message, customerId | filter @message like /customerIDIndex/ | stats count(*) as requestCount by customerId | sort requestCount desc | limit 20",
  "startTime": "<alarm_time - 1 hour>",
  "endTime": "<alarm_time + 30 min>"
}
```

Look for customer IDs with unusually high request counts.

---

##### Step 3: Check Known Test Customer IDs

**Game Day Test Customer IDs:**
- `AAUN6GRDK1Y6Y`
- `A1996B4MGPVTDP`
- `A3I1OCZ3CE1A7S`

If high-TPS customer matches → Likely Game Day testing

---

##### Step 4: Analyze Pattern

**Tool:** `CloudWatchLogsTool.queryLogs`
```json
{
  "logGroupName": "/aws/lambda/WarrantyServices-API",
  "queryString": "fields @timestamp, @message | filter customerId = '<HIGH_TPS_CUSTOMER_ID>' | stats count(*) as calls by bin(5m) | sort @timestamp",
  "startTime": "<alarm_time - 2 hours>",
  "endTime": "<alarm_time + 1 hour>"
}
```

**Game Day indicators:**
- Sudden spike then drop
- Concentrated in short window
- Matches known test IDs

---

##### Step 5: Resolution

**If Game Day Testing Confirmed:**
- No action required - expected test traffic
- Monitor for recurrence outside test windows

**If NOT Game Day Testing:**
- Escalate for investigation
- Include: alarm name, trigger time, customer ID, request pattern

---

#### Example

**Ticket:** V1998698335

**Analysis:**
1. Alarm: WSA-DDB-CustomerIDIndex-HighTPS
2. Found customer `AAUN6GRDK1Y6Y` with 50,000+ requests in 10 minutes
3. Customer ID matches known Game Day test ID
4. Pattern: sudden spike, immediate drop

**Resolution:** Confirmed Game Day testing, no action required

---

---

#### Additional Scenario: KeyTable Main Index High RCU Alarm

##### When to Use
- Alarm: `DDB HighConsumedReadCapacity KeyTable`
- High RCU spike on the main index (not customerIDIndex)

##### Root Cause

RCUs spike if there is high TPS of queries OR if a consistent TPS of queries suddenly returns a lot of data. A customer with many test devices (e.g., 30+ devices) can cause massive data returns per query, spiking RCUs.

##### Procedure

**Step 1:** Check if WSA was called for known high-data customer IDs (same as Step 3 above).

**Step 2:** If not a known test customer, trace through code paths that invoke the KeyTable. Look for requests with high latency on methods annotated with `@TimeAndCountMetrics`:

```json
{
  "operation": "QUERY_CLOUDWATCH_LOGS",
  "params": {
    "queryString": "fields @timestamp, @message | parse @message '\"*.Time\":*,' as method, latency | filter latency > 5000 | sort latency desc | limit 20",
    "startTime": "<alarm_time_minus_1h_epoch>",
    "endTime": "<alarm_time_plus_30m_epoch>"
  }
}
```

**Step 3:** Identify which requests caused the spike and whether it's transient or ongoing.

---

#### Stop Conditions

Escalate if:
- Cannot query CloudWatch logs
- Customer ID not in known test list AND pattern unclear
- TPS spike is ongoing
- Multiple customer IDs showing high TPS

</details>

---

<details>
<summary>

### 2.3. SOP: Missing Marketplace Configuration Alarm

</summary>


#### Applicability

**Use this SOP when:**
- Error: "No Canonical_marketplace_id for encryptedMarketPlaceId"
- Error: "No lwconfigs for marketplace `###`, devASIN `default`"
- Error: "Something unexpected went wrong when determining Limited Warranty period"
- New marketplace launched at Amazon but G2S2 config not updated

**DO NOT use if:**
- Error is about a specific ASIN config (use g2s2-config-fallback SOP)
- Error is about EW config marketplace mismatch (use warranty-type-mismatch SOP)

---

#### Procedure

##### Step 1: Confirm the Error Pattern

```json
{
  "operation": "QUERY_CLOUDWATCH_LOGS",
  "params": {
    "queryString": "fields @timestamp, @message | filter @message like /No Canonical_marketplace_id for encryptedMarketPlaceId/ | stats count(*) as occurrences by bin(1h) | sort @timestamp desc",
    "startTime": "<alarm_time_minus_24h_epoch>",
    "endTime": "<now_epoch>"
  }
}
```

##### Step 2: Extract the Missing Marketplace ID

```json
{
  "operation": "QUERY_CLOUDWATCH_LOGS",
  "params": {
    "queryString": "fields @timestamp, @message | filter @message like /No Canonical_marketplace_id for encryptedMarketPlaceId/ | sort @timestamp desc | limit 10",
    "startTime": "<alarm_time_minus_24h_epoch>",
    "endTime": "<now_epoch>"
  }
}
```

Extract the `encryptedMarketPlaceId` value from the log message.

##### Step 3: Escalate for Marketplace Update

This requires updating the `@KWSConfig_Live` Label Stream in G2S2 with the new marketplace mapping. Provide the oncall engineer with:
- The encrypted marketplace ID from the logs
- Error frequency and start time
- Link to marketplace update instructions: https://w.amazon.com/bin/view/KiSIT/Secure/KindleWarrantyService/Marketplace_Changes/

---

#### Stop Conditions

Escalate if:
- Multiple marketplace IDs are missing
- Error volume is high and increasing
- Cannot identify the encrypted marketplace ID from logs

</details>

---

<details>
<summary>

### 2.4. SOP: OverwritingUnitOfWorkOperationRequest Alarm

</summary>


#### Applicability

**Use this SOP when:**
- Ticket references the `OverwritingUnitOfWorkOperationRequest` alarm
- Metric namespace `CleLambda` (WarrantyServicesLambda)

**Common Alarm Names:**
- `OverwritingUnitOfWorkOperationRequest`

---

#### Background

This is a metric-only alarm with a 0/1-datapoint threshold — it trips on ANY
non-zero emission. The metric is emitted by
`UnitOfWork.provideOperationRequest()` in WarrantyServicesLambda when a stale
`OperationRequest` lingers on a reused warm-Lambda thread and is overwritten.
The overwrite is non-destructive, so customer impact is low.

Because it is metric-only, a CloudWatch Logs query for the event will return
0 hits — that is expected and does NOT mean the alarm is stale.

---

#### Procedure

##### Step 1: Check Datapoints

Confirm whether the alarm fired on a single datapoint or a sustained pattern.

##### Step 2: Check for Correlated Alarms

Look for any correlated WSA alarms or customer-impact signals in the same
time window.

##### Step 3: Resolve

**If single datapoint + no correlated alarms + no customer impact:**
- Resolve as a transient environment issue. No code action required.

**If sustained or correlated with other alarms:**
- Escalate for investigation of warm-Lambda thread / UnitOfWork handling.

---

#### Stop Conditions

Escalate if:
- The alarm fires repeatedly or on sustained datapoints
- There are correlated alarms or customer-impact reports
- There is any evidence the overwritten OperationRequest caused an incorrect operation

</details>

---

<details>
<summary>

### 2.5. SOP: Replacement Product for Already-Bound Binding Alarm (KRIS `IsBundled` gap)

</summary>


#### Applicability

**Use this SOP when:**
- Alarm name `Sev5 Replacement Product for Already-Bound Binding` (us-east-1 / us-west-2)
- Metric `BindingAlreadyBoundToProductDuringReplacement`, namespace `CleLambda` (WarrantyServicesLambda)
- `WSAMainLogs` ERROR line: `Binding [<bindingId>] for replacement Order [<order>] is already bound to a non-BundledBaseUnit Product: [<product>]`

**Related:** this is the fleet-alarm view of the customer-facing
[`kris-isbundled-orphaned-replacement`](../../customer-issues/kris-isbundled-orphaned-replacement/README.md)
SOP — use that one for the per-warranty remediation detail.

---

#### Background

Metric-only alarm with a 0/1-datapoint threshold: it trips on ANY non-zero emission and **latches in ALARM** until emissions stop for an evaluation period. Each emission is one replacement fulfillment where WSA tried to swap the replacement product onto the warranty's binding but the binding still held a **non-bundled-base-unit product**, so the swap was skipped — the KRIS `isBundledBaseDevice` classification gap (KRL-30482 / KRLFRI-97). The warranty is left stranded on the stale product and the replacement device the customer received does not get that binding.

Notes:
- Retries repeat for the same order, so raw datapoint/hit counts overstate impact — **dedupe by order**.
- A single order whose fulfillment keeps retrying will keep the alarm latched, even after every other impacted order is fixed.
- The `product` in the log line is the **stale** product on the binding, **not** the replacement DSN.

---

#### Procedure

##### Step 1: Enumerate impacted orders (dedupe)

Run a CloudWatch Logs Insights query over `WSAMainLogs` for the review window (match the region; extend to ~4 weeks for a latched Sev5):
```
fields @timestamp, @message
| filter @message like /is already bound to a non-BundledBaseUnit Product/
| parse @message "Binding [*] for replacement Order [*] is already bound to a non-BundledBaseUnit Product: [*]" as bindingId, orderId, product
| stats count(*) as retries, min(@timestamp) as firstSeen, max(@timestamp) as lastSeen by orderId, bindingId, product
| sort retries desc
```
Each row is one impacted order. Note orders still emitting near `lastSeen = now` — those are what keep the alarm latched.

##### Step 2: Find the real replacement DSN for each order

The log only names the stale product. Find the device actually fulfilled on the order:
```
fields @message
| filter @message like /CreateLimitedWarrantyForDeviceShipmentRequest/ and @message like /<ORDER>/
| parse @message "serialNumber=*, type" as replacementDsn
| stats count(*) by replacementDsn
```

##### Step 3: Read source of truth and triage each order

- `QUERY_KEY_TABLE_BY_ORDER { "orderId": "<ORDER>" }` → get the `warrantyId`; then
  `QUERY_KEY_TABLE { "warrantyId": "<WARRANTY_ID>" }` → confirm the **active** binding holds the order + the stale product, `invalidated: false`, and the `owner`.
- `GET_WARRANTIES_BY_DEVICE { "dsn": "<REPLACEMENT_DSN>" }` → inspect the replacement device's warranty state.

Branch on the replacement device's state:

- **Replacement device has NO active warranty** (empty list, or only an *invalidated* prior-owner warranty, or only an encrypted-zero `A23ZP02F085DFQ` default-owner placeholder) → **fixable stranded case.** Apply the `kris-isbundled-orphaned-replacement` SOP: device-scoped `UNBIND` of the stale product, verify the order stayed on the binding, `BACKFILL_LIMITED_WARRANTY` the replacement DSN, verify (`GET_WARRANTY_CLAIM_CODE` eligible, owner + claim preserved). A backfill legitimately invalidates the encrypted-zero placeholder as part of fulfillment.

- **Replacement device ALREADY has its own active warranty** (especially bound as a proper `AmazonDeviceBundledBaseUnitProduct`, and/or it has already been claimed onward) → **DO NOT backfill.** The customer is already covered on that warranty; the warranty on the alarm order is an **orphaned duplicate** that never transferred. Confirm the customer is not blocked (`GET_WARRANTY_CLAIM_CODE` on the device they hold returns an eligible code). The cleanup is to `INVALIDATE_WARRANTY` on the **stranded/orphaned** warranty (the one stuck on the alarm order) — **gate behind oncall/human approval** — which also stops the metric. Backfilling here would create a duplicate/conflicting binding on an already-covered device.

##### Step 4: Resolve

Once every impacted order is either remediated (unbind + backfill) or confirmed to be an orphaned duplicate with the customer covered elsewhere (orphan invalidated or escalated), no new emissions occur and the latched alarm returns to OK on the next clear evaluation period. Resolve when all impacted orders are handled and no customer is blocked.

---

#### Stop Conditions

Escalate if:
- The replacement device has an active warranty owned by a **real, different customer** (not the encrypted-zero placeholder) → cross-customer, STOP.
- Multiple warranties are tangled for the same customer and it is unclear which is canonical.
- `UNBIND` / `BACKFILL_LIMITED_WARRANTY` / `INVALIDATE_WARRANTY` errors, or verification shows an unexpected state.
- The alarm fires on a sustained/rising pattern across many new orders (possible regression in the KRIS classification) rather than a backlog of known stranded orders.

</details>

---

## 3. Human-Only Documentation

<details>
<summary>

### 3.1. Andes Table Data Quality Issues

</summary>


Tickets with "RSE_COPY_VALIDATION_ISSUE" indicate published data violating the Andes table schema.

Reference: https://t.corp.amazon.com/V787620038

#### Procedure

1. **Identify bad data:** Follow https://w.amazon.com/bin/view/BDT/Products/Andes3.0/Subscriptions/Datashare_DQ/#HHowtoExamineBadRecordfromInfoinTicket
2. **Find all corrupted records:** Use Cradle (https://datacentral.a2z.com/cradle#/WarrantyServices/profiles) with manual query profile. Output to S3 bucket `wsa-andes-data-bucket`.
3. **Fix bad data** manually or via appropriate method
4. **Republish** using oncall lambda redrive for affected warranties
5. **Create new table version** at https://datacentral.a2z.com/providers/kws (bad data is stuck in the stream — fixing source doesn't fix stream)
6. **Pause DataCraft pipeline** > Create new version (backfill from Andes) > Wait for completion > Mark Active > Update pipeline destination > Re-enable > Deprecate old version

</details>

---

<details>
<summary>

### 3.2. DMS Event Subscription Migration (V1 → V2) — Operations SOP

</summary>


Subscribe WSA's SQS queues to DMS V2 (Enhanced Events) SNS topics, confirm, and
validate processing. Use per stage (Beta → Gamma → Prod) for this migration
(P401610471) and future DMS event onboarding.

#### 0. Prerequisite — DMS-360 access

Requires manager-approved LDAP group **`ManagerApproved-dms360-event-management`**
— request at https://permissions.amazon.com/group.mhtml?target=10905547. Without it
you cannot create/confirm/remove subscriptions.

#### 1. Subscribe in DMS-360 (one stage at a time)

Open the stage endpoint → select the **stage** in the dropdown → enter the **queue
ARN** → event type **Registration events** → select the **`_Global_V2`**
(Non-Optimistic) topics → Submit. The SQS policy already dual-allows V2 (via CDK);
no manual policy edit.

| Stage | DMS-360 endpoint (select stage in dropdown) | RegistrationEventsQueue / FroEventsQueue | DMS SNS acct |
|---|---|---|---|
| Beta  | https://dms-360.integ.amazon.com/events/home | `arn:aws:sqs:us-west-2:706697182301:{RegistrationEventsQueue\|FroEventsQueue}` | 215985707738 |
| Gamma | https://dms-360.aka.amazon.com/events/home | `arn:aws:sqs:us-east-1:629831327937:{…}` | 409489657119 |
| Prod  | https://dms-360.aka.amazon.com/events/home | `arn:aws:sqs:us-east-1:893336269592:{…}` | 117522526554 |

> ⚠️ Gamma uses the **prod** endpoint with **Gamma** selected. `dms-360-gamma.aka.amazon.com`
> is the legacy V1 host → `400 Bad Request`.

#### 2. Confirm the subscription (from CloudWatch Logs)

Cross-account SNS→SQS does **not** auto-confirm — SNS puts a one-time
`SubscriptionConfirmation` in the queue; the handler skips it and **logs the
SubscribeURL**. After the queue's delivery delay (`RegistrationEventsQueue` ~2 min;
**`FroEventsQueue` 15 min**), find the SubscribeURL in the handler log group:

- Registration → `/aws/lambda/RegistrationEventHandlerContainerLambda`
- FRO → `/aws/lambda/FroEventHandlerContainerLambda`

**CloudWatch Logs Insights** (run in the stage's region; select the log group above,
then run — the `parse` pulls the URL out directly):

```
fields @timestamp, @message
| filter @message like /SubscriptionConfirmation/
| parse @message "SubscribeURL=[*]" as subscribeUrl
| sort @timestamp desc
| limit 20
```

**Or via CLI** (`filter-log-events`):

```
aws logs filter-log-events --log-group-name <log-group> \
  --filter-pattern 'SubscriptionConfirmation' --region <stage-region>
```

**Open the `subscribeUrl` in a browser** (a GET confirms it; success returns XML with
a real `<SubscriptionArn>`). Confirm every subscribed topic. Don't pause the ESM or
poll the live queue; if missed, the URL is also readable from the DLQ.

#### 3. Validate processing

Sign off a stage only when all hold:

| Metric | Expected |
|---|---|
| `<Event>V2` (e.g. `AccountCreatedV2`) | rises to ~V1 baseline |
| `<Event>V1` | steady in dual-run; → 0 only after V1 is cut |
| `<Event>V2.ParseFailure` | **0** |
| topic-ARN "received" vs `<Event>V2` | track ~1:1 (no gap) |
| DLQ depth / Lambda `Errors` | baseline (0) / ~0 |

Healthy Beta dual-run (2026-08-17): AccountCreated V1 8,923 / V2 8,927; Account
Resurrected V1 2,539 / V2 2,539; RegistrationRequested V2 39,884 (V2-only, no V1
sub) — all ParseFailure 0, DLQ 0.

#### 4. Graphs

Dashboard **`InternalServiceMonitoring-<domain>-<region>-<realm>`** → **DMS Event
Handler → Custom Metrics** (wiki: Internal Monitoring → Beta=FE/us-west-2,
Gamma=NA/us-east-1, Prod=NA/us-east-1; open the live CloudWatch console — the wiki
caches). Check:

- **`<Event>`: SNS Received vs Processed** — Received vs Processed V2 should overlap;
  a gap = parse failures/stall.
- **`<Event>V2.ParseFailure`** — flat 0 (non-zero cuts a Sev3 SIM ticket in **prod**
  only; Beta/Gamma are dashboard-watch).
- **`<Event>V1` vs `<Event>V2`** — cutover progress.

Metrics are under the **container** namespaces `RegistrationEventHandlerContainerLambda`
/ `FroEventHandlerContainerLambda`, **dimensionless**.

#### 5. After sign-off

Bake ~1 day dual-run → remove V1 subscription in DMS-360 → mirror the SQS policy in
CDK → next stage.

</details>

---

<details>
<summary>

### 3.3. Edge Cases (Manual Fixes)

</summary>


Issues requiring direct database edits, external tools, or manual intervention.

#### Force Limited Warranty Binding to be Active

Old KWS warranty (`Warranty-XXXXXXXXXX`) with no active bindings.

1. Query Warranty ID in Event Source
2. Find first `WarrantyBackfilled` event
3. Set `isActive` to `true` (no quotes), `unbindTime` to `null` (no quotes)
4. Only edit Event Source, NOT the MV. Remove stray `"` or `"/` characters.
5. Redrive warranty to MV if needed.

#### KET Device with Wrong ASIN

Online: Use https://spectator-g7g.amazon.com/FionaSpectatorService/FulfillFiona.jsp with correct KET ASIN. Device gets deregistered — CS must re-bind.

Offline: Cannot refulfill. Ask Concessions for exception.

#### Different DSN Than Expected Shipped

Option 1 (preferred): Manually write correct DSN into database (preserves history).
Option 2: Refulfill with correct DSN (creates new LW, loses history).

#### Echo Buds Multi-Component EW Replacement

EW can only bind to one component. Extend LW coverage for excess components. Long-term: WSA-1756.

#### EW Wrong Expiration Date

Have CS file exception. Tracked: https://sim.amazon.com/issues/KindleWarrantyService-494

#### BI Duplicate Data

Find claimId > search Event Source EntityIdIndex for `Claim-<claimId>` > get warrantyId > oncall lambda RERUN_DATA_PUBLICATION with correct table (CLAIM, WARRANTY_MAIN, or EXTENDED_WARRANTY).

#### BuyNewEW Alarm / SquareTrade Issues

If BuyNewEW volume drops to 0, contact @kulsonam for SquareTrade coordination. Treat as Sev2.5.

Reference COEs: https://www.coe.a2z.com/coe/254929/content

SquareTrade merchant: `amzn1.merchant.o.A3B4VRMPOFUHJ3`
FRPG permissions: `tortuga-viewer-uci` LDAP

#### Client Onboarding (IAM Auth)

Wiki: https://w.amazon.com/bin/view/WarrantyServices/PartnerTeams/Onboarding/

NAWS clients: https://code.amazon.com/packages/WarrantyServicesCDK/blobs/mainline/--/lib/authentication/clients/configuration/AWSPrincipalClientsConfig.ts
MAWS clients: https://code.amazon.com/packages/WarrantyServicesCDK/blobs/mainline/--/lib/authentication/clients/configuration/TurtleClientsConfig.ts

Note: Turtle ignores parent DEV-DSK hostclass — each DEV-DSK must be onboarded individually.

</details>

---

<details>
<summary>

### 3.4. G2S2 & RMP Configuration

</summary>


#### G2S2 Overview

G2S2 stores WSA warranty configuration. Editor: https://g2s2-editor.amazon.com/editor/#n=25&p=0&t=tables&sv=%40KWSConfig_Live

##### Key Tables
- `klaw_kws_limit_warranty_configs` — Limited warranty configs
- `klaw_kws_deviceasins` — Device ASINs (must exist before LW config)
- `klaw_kws_extend_warranty_configs` — Extended warranty configs

##### Permissions
- Table/label permissions: https://g2s2.corp.amazon.com/secureAuthoring
- Direct access: https://bindles.amazon.com/software_app/KindleWarrantyService

#### Warranty Onboarding Procedure (NEW configs only)

> **This procedure only ADDS a config for an ASIN that has none yet. To change an
> existing config, see [Updating an Existing Config](#updating-an-existing-config) below.**

1. Download CSV/XLSX from onboarding SIM
2. Convert to CSV if needed, validate in text editor (no empty lines, proper quoting)
3. Upload to S3: https://s3.console.aws.amazon.com/s3/buckets/warranty-configuration-lambda-bucket-prod
4. Trigger processing by **directly invoking** the config Lambda
   (`WarrantyConfigurationS3toG2S2ContainerLambda`, NA = us-east-1) with payload:
   ```json
   {"operation":"UPLOAD","s3Key":"<your-file-name.csv>"}
   ```
   Note: `s3Key` is the object key only (no bucket, no `s3://`, no folder prefix). The bucket
   comes from the Lambda's `CONFIGURATION_S3_BUCKET` env var.
   > **Important:** Simply dropping the file in the S3 bucket does NOT auto-process it in the
   > current deployment. The S3-event path returns `"Missing operation in request"` and does
   > nothing — the Lambda only handles direct invocations with an `operation` field.
   > The Lambda has reserved concurrency = 1, so if you see `Rate Exceeded`
   > (`ReservedFunctionConcurrentInvocationLimitExceeded`), wait and invoke once — do not retry
   > back-to-back.
5. Check Lambda logs for `"Configuration uploaded successfully"`
6. Verify in G2S2 by searching uploaded ASINs

#### Updating an Existing Config

**The upload procedure above cannot modify a config that already exists** — it is insert-only.
The upload path (`WarrantyConfigurationG2S2Impl.uploadLimitedWarranty` /
`uploadExtendedWarranty`) behaves as:

| State in G2S2 for (canonical marketplace + ASIN) | Uploaded config | Result |
|---|---|---|
| No existing config | — | Inserts |
| Existing config, identical | matches | No-op ("already exists") |
| Existing config, **different** | differs | **Throws** `"...different from an existing configuration"` — nothing applied |

Because a *correction* is by definition different from the existing config, it always hits the
throw. **Do NOT re-upload to fix an existing config.** Instead, edit it directly in G2S2:

1. Open the editor: https://g2s2-editor.amazon.com/editor/#n=25&p=0&t=tables&sv=%40KWSConfig_Live
2. Select the table (`klaw_kws_limit_warranty_configs` for LW,
   `klaw_kws_extend_warranty_configs` for EW).
3. Find the row by **device ASIN + canonical marketplace id** (e.g. US = `1`).
4. Edit the field(s) (e.g. LW duration 90 days → 1 year), save, and promote per secureAuthoring
   (requires config-owner write access).
5. **Refresh affected existing warranties** — config changes are NOT retroactive to already-created
   warranties. For each affected warranty run the oncall op
   `UPDATE_WARRANTY_CONFIGURATION` with `fetchAsin=true` (re-reads the current G2S2 config and
   recalculates the warranty's term).
6. Verify in the editor and via `GET_WARRANTIES_BY_DEVICE`.

#### RuleManagementPlatform (RMP)

Rulesets: https://rmp-na.amazon.com/?region=USAmazon&ruletype=ReplacementOptionsRuleset&schema=WarrantyServicesSchema

##### Modifying Rulesets
1. Click Live Ruleset Instance ID > Find rule > Edit > Save > Validate
2. Commit changes > Promote to AUDITING > Approve > Promote to LIVE
3. Repeat for all marketplaces
4. Update wiki: https://w.amazon.com/bin/view/WarrantyServices/BusinessRulesManagement/

</details>

---

<details>
<summary>

### 3.5. Infrastructure Emergencies

</summary>


#### Prod Stack Deletion

Impact depends on resources in the stack:
- **Deterministic physicalIds:** Emergency deployment from Gamma to Prod
- **Dynamic endpoints (API Gateway):** See API Gateway section below
- **VPC with BubbleBridge:** See BubbleBridge section below

##### BubbleBridge Stack Deletion

Reference COE: https://www.coe.a2z.com/coe/232378/content

Rolling back DOES NOT WORK — VPC gets recreated with a new VPC ID. Mitigation: roll back to recreate VPC, then perform emergency BubbleBridge onboarding with the new VPC.

##### API Gateway Stack Deletion

Reference COE: https://www.coe.a2z.com/coe/235124/content

API Gateway dynamically generates endpoint URLs. WSA provides a static DNS that resolves to the dynamic endpoint. If re-deployed, DNS resolution must be updated.

#### Lambda OOM Metaspace

AWS Lambda hardcodes MaxMetaspaceSize to 10% of configured memory. Above 90% usage causes OutOfMemoryError.

**Short-term:** Lambda > Configuration > General Configuration > Increase memory > Publish new version > Weighted alias cutover

**Long-term:** Increase Lambda memory in CDK.

#### MaterializedView / DormantWarranty StreamHandler Errors

##### Iterator Age Alarm
DDB Stream messages expire after 24 hours. Causes:
1. Queue filling faster than processing — increase parallelization factor on Lambda trigger
2. Lambda stuck on a record — investigate, potentially direct prod push (2-person rule)

##### Lambda Failures / DLQ Alarms
Failed messages go to RecordFetcherFunction then retry lambda. Likely malformed warranty requiring manual intervention. DLQ build-up > 24 hours = data loss risk.

##### DataFetcherDLQ Sev2
Manual recovery with `aws dynamodbstreams get-shard-iterator` and `get-records`. If recovered, send to RecordQueue and delete from DLQ.

#### Scaling Service

Wiki: https://w.amazon.com/bin/view/WarrantyServices/Oncall/Scaling

Emergency scaling: https://w.amazon.com/bin/view/WarrantyServices/Oncall/Scaling#HEmergencyWSAScaling

#### Disabling Lambda/SQS Connection

Lambda > active version/alias > Configuration > Triggers > Edit > Uncheck "Activate Trigger" > Save

#### Billing Alarm

Billing metrics accumulate in us-east-1. Check "All > Billing > By Service" to identify spiking resource. Dashboard: https://w.amazon.com/bin/view/WarrantyServices/Internal/Dashboards/InternalMonitoring/Prod/NA/

#### Certificate Expiration Risk (CCNS_CERT_EXPIRING)

A `[Certificate Expiration Risk]` (CCNS_CERT_EXPIRING) Shepherd risk on `warrantyservices-dev.<region>.amazon.com` is caused by leftover **pre-Tardigrade L7 VIPs** that still bind the old certificate.

##### Procedure

1. **Enumerate all leftover VIPs** in VIP Management. Search by:
   - hostclass `MYX-DEVELOPMENT-1AWSA-*`
   - `original-warrantyservices-dev-<region>.<region>.proxy.amazon.com` (surfaces the `-443`, `-80`, and `BUSTARD-ORIGINAL` VIPs)
2. **Confirm zero traffic** on each VIP.
3. **Delete every leftover VIP** — disabling is NOT sufficient. The CCNS scanner keeps emitting after a disable; only deletion clears the risk.
4. **Wait ~36 hours** after all deletions for the metric to clear, then resolve with rootCause `Mandate - Shepherd Risk`.

##### If VIP deletion is blocked

`BustardClient undef` / Vipster 500 errors during deletion indicate a VIP Management DNS-delegation outage, not a WSA issue. Watch the L7 "Is VIP Management Down?" VIP Portal for a Warn → OK recovery before retrying; do not delete until tooling confirms the VIP is non-globalized.

There is no self-service API workaround for pre-Tardigrade VIPs — deletion must go through the L7 team.

**Escalation:** CTI `Loadbalancers / Console and Tools / VIP Management UI`, resolver group **L7 Console and Tools** (sub-teams: l7-console@, l7-rtsb@ for DNS, l7-platform@ for classic Netscaler delete ops).

</details>

---

<details>
<summary>

### 3.6. Oncall Reference

</summary>


Quick reference for oncall engineers covering policies, tools, contacts, and triage procedures.

#### Going On Call

- Read recent oncall handoffs: https://quip-amazon.com/lFo0OofzQFg0/KWS-On-call-Handoffs
- Review dashboards: https://w.amazon.com/bin/view/WarrantyServices/Internal/Dashboards/

#### Triage Checklist

1. Check system health (5 min) via dashboards. Check all prod regions for drops/spikes.
2. Work trouble ticket queues: https://t.corp.amazon.com/issues/?q=extensions.tt.status%3A%28Assigned%20OR%20Researching%20OR%20%22Work%20In%20Progress%22%20OR%20Pending%29%20AND%20extensions.tt.assignedGroup%3AWarrantyServices
3. Priority: Sev2 > Customer-facing > Internal customer-facing > Onboardings with deadlines > Maintenance

#### Production AWS Account Best Practices

- Access Prod via https://conduit.security.a2z.com/accounts (defaults to read-only)
- Use `WSADeveloperOncallRole` instead of Admin — it DENIES deletion on critical resources
  - Bindle: https://bindles.amazon.com/resource/amzn1.bindle.resource.vv6lzzillbxxkebjpzvq
- Log out of Prod when done
- Minimize working in both dev and Prod accounts simultaneously
- Prod stack deletion requires 2-person operation (termination protection must be manually disabled first)

#### Conduit Down Workaround

https://w.amazon.com/bin/view/ConsumerCloudTrust/Conduit/Features/ConduitWebsite/FAQ#HIfconduitwebsiteisdown2ChowcouldIaccessmyAWSaccount3F

#### Coral Service Warning

When sending payloads to WSA Coral Service via BOTO3/CLI: Coral uses **epoch seconds** for timestamps. Using epoch milliseconds will set dates far in the future and BREAK WSA. See: https://sage.amazon.com/questions/25905

#### Ticket Tags in Use

| Tag | Description |
|-----|-------------|
| Un-cancel Claim | Claim cancellation reversal |
| KRIS ASIN Update | KRIS replacement ASIN issue |
| KDSS Data Issue | KDSS fulfillment data problem |
| Missed SOP | CS missed standard procedure |
| EW Binding Eligibility | EW binding issue |
| WSA Tools Feature Gap | Missing WSA Tools functionality |
| Dormant Warranty | Dormant warranty issue |
| Dormant Warranty - GetWarrantyClaimCode | Dormant warranty blocking claim codes |
| EW Previously Bound | EW already bound to another device |
| Invalidated Warranty | Warranty incorrectly invalidated |
| KWS Warranty | Legacy KWS warranty issue |
| FRO ASIN | First Radio On ASIN issue |
| Failed Shipment | Shipment delivery failure |
| JP Worry Free | JP marketplace Worry Free issue |
| RCH Order | Offline purchase order |
| OBA Order | Out of Box Audit order |

#### CTIs and Resolver Groups

- **KDSS:** Digital Media Technology / Kindle Device Sales / KindleDeviceSalesService
  - Wiki: https://w.amazon.com/bin/view/DCS_Chennai/DeviceManagementService/KindleDeviceSalesService
  - Oncall: https://oncall.corp.amazon.com/#/view/dmsbifrost-dev-primary/schedule
- **KRIS:** Digital Media Technology / Kindle Reverse Logistics Tech / Kindle Replacement Info Service
- **D2Concessions:** Customer Service / CSC/Texas / D2Concessions
  - Office Hours: https://w.amazon.com/bin/view/D2AS/Technology/D2Concessions/ContactUs
- **CE Tech Warranties:** https://w.amazon.com/bin/view/Warranties/Contact

#### Warranty Onboarding POCs

- **Limited Warranty:** priyalsm@ — reassign LW config issues via CTI **Digital Media Technology / Kindle Reverse Logistics / Replacement Config Issue** (resolver group **ADRL NPI LRM**)
- **Extended Warranty:** kulsonam@

#### Tools

| Tool | URL | Purpose |
|------|-----|---------|
| WSA Tools | https://tools.warranty-services.devices.amazon.dev/ | Primary troubleshooting UI |
| Cedric (AI) | https://console.harmony.a2z.com/internal-ai-assistant?persona=09ebf5bc-6347-4414-a300-abe900441f83 | Chat-based troubleshooting |
| OnCall Lambda | See wiki | Low-level WSA operations |
| DMS-360 | https://dms-360.aka.amazon.com/ | Device Type / ASIN mappings |
| Grass | https://grass.integ.amazon.com/ | Order/purchase/shipment lookup |
| CSCentral | https://cscentral.amazon.com | CS representative portal |
| Amazon Translate | https://translate.amazon.com | Internal translation |
| G2S2 Editor | https://g2s2-editor.amazon.com/editor/ | Warranty configuration |

#### Common Informational Responses

**EU 2-year warranty law:** Tell CS to override on their end. Tag: "Missed SOP"

**CSCentral cached warranty duration:** CSCentral displays cached values. Assure CS they can likely file a replacement.

**Cannot make claim due to active service event:** Warranty is already being replaced. Reassign to RL Tech team.

**5XX RegisterWarrantyClaim from KROBS:** KROBS sends bad data when clearing backlog. If only KROBS calls fail and Slapshot is fine, mark as false alarm.

</details>

---

<details>
<summary>

### 3.7. Pipeline & Deployment

</summary>


#### Packaging Approval Workflow Failed

When adding new resources or pipeline changes, manually approve changes in the approval workflow.

#### New Lambda Deployment S3 Error

Chicken-and-egg problem:
1. Send another deployment through packaging stage (can be empty build request)
2. If still failing, completely delete the stack and retry from Pipelines UI
3. WSA CDK often retains resources on deletion — delete ALL retained resources AND the stack

#### NAWS Pipeline Rollback

1. Pipeline > Emergency Actions > Single Target Rollback
2. Select stage > last approved version > Preview Rollback
3. Verify diff > Provide reason > Initiate Rollback
4. Monitor CloudFormation: `UPDATE_COMPLETE` = done; `UPDATE_ROLLBACK_FAILED` = click ContinueUpdateRollback

#### Fixing Broken Version Set

Reference: https://sim.amazon.com/issues/WSA-2442

1. Merge `WarrantyServices/release` into `WarrantyServices/release-PipelineFix`
2. Merge from `live` into PipelineFix
3. Prune broken packages
4. Pull locally (new workspace), fix (typically `bb app updateSnapshot`)
5. Publish CR, merge, then manually build into VS
6. Switch workspace back to `WarrantyServices/release`

#### Manually Uploading Lambda Code (2-PERSON REVIEW)

1. Clean, currently-live workspace
2. `bats transform -x AWSLambda-1.0 -t package-MajorVersion -p package-MajorVersion`
3. Upload zip to S3 (same region as Lambda)
4. Lambda > Code > Upload From > S3 link
5. If using alias, cutover to new version

#### Manually Uploading Docker Code (2-PERSON REVIEW)

1. Clean, currently-live workspace
2. `bats transform -x DockerImage-1.0 -t WarrantyServicesLambda-1.0 -p WarrantyServicesLambda-1.0`
3. Tag and push to ECR, update Task/Service, force new deployment

</details>

---

<details>
<summary>

### 3.8. Privacy Compliance (Boomerang / AEDU / SandFire)

</summary>


#### Overview

WSA handles GDPR compliance through Boomerang, processing requests from AEDU (DSAR) and SandFire/OD3 (Data Deletion).

Lambda code: https://code.amazon.com/packages/WarrantyServicesPrivacyComplianceLambda/trees/mainline

#### Redriving Failed Requests

1. Go to Boomerang: https://boomerang.corp.amazon.com/#/workflow-explorer
2. Use Boomerang Workflow ID (from ticket) or service-specific ID
3. Request Type: `GDPR.Delete` (SandFire) or `GDPR.DSAR` (AEDU)
4. Team: WarrantyServices

##### Finding AEDU Request IDs
Portal: https://portal.aedu.privacy.a2z.com/ > Retail-DSAR > Data Owners > WarrantyServices > Data Requests

The redrive ID is the UUID in the nav header.

#### Testing

##### Beta
- AEDU: https://portal.beta.aedu.privacy.a2z.com/ > Create Data Request
- OD3: https://portal.data-deletion.privacy.a2z.com/ > Workflow Validation > New Request (Beta)

##### Gamma
- AEDU: https://portal.gamma.aedu.privacy.a2z.com/
- OD3: Same portal, select Gamma

#### Changing DSAR Response Schema

CDK: https://code.amazon.com/packages/WarrantyServicesCDK/blobs/mainline/--/lib/stacks/PrivacyComplianceInfraStack.ts

Steps: Modify Lambda response > Update Boomerang UI columns > Deploy > Test via AEDU portal

Production cutover: Block promotions > Pause queue > Update Boomerang schema > Deploy > Re-enable queue > Redrive failures

</details>

---

