diff --git a/AGENTS.md b/AGENTS.md
index 1396e5f..2df28fb 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -127,6 +127,15 @@ session with **no other memory of this project**. So:
`PayWithSats` sheet (NWC → WebLN → Cashu melt, falling back to the seller's
`lud16`). ⚠️ The sheet is **mounted only while open** so its wallet hooks
don't run on every grid card.
+ - **Shipment / fulfilment (2026-10-01):** listings carry an optional
+ `["fulfilment","pickup"|"ships"|"both"]` (selling only) — a create-page
+ selector (default **pickup**), a card badge, and a **Pickup/Ships** filter on
+ `GearSwapPage`. ⚠️ **The app never collects an address**: a `ships` deal
+ exchanges it privately in the trade chat (NIP-17), and `ListingTradeActions`
+ nudges **escrow** for shipped deals. No KYC rail, no carrier API, no labels.
+ - **Low-diversity ring warning (2026-10-01):** beyond the single-partner
+ warning, `TradeReputationCard` flags `verified >= 5 && verifiedCounterparties
+ <= 2` — "most confirmations come from very few accounts".
- **Cashu escrow** (marketplace): time-locked **P2PK** (lock to seller + buyer
refund key + locktime) — see **`ESCROW.md`** and `src/lib/cashuEscrow.ts`
(unit-tested). Protocol: `cashu_token` on the `31872`; each user advertises a
diff --git a/NIP.md b/NIP.md
index 8b6cf3e..ed9a52d 100644
--- a/NIP.md
+++ b/NIP.md
@@ -584,6 +584,7 @@ Gear listings use the NIP-99 Classified Listings format (kind 30402) for peer-to
| `price` | Price amount and currency (e.g., `["price", "50", "USD"]`) - required if price_type is `fixed` |
| `condition` | Item condition: `new`, `like_new`, `good`, `well_used` |
| `size` | Item size (varies by category) |
+| `fulfilment` | How the deal is fulfilled: `pickup`, `ships`, or `both`. ⚠️ The app **never collects an address** — a `ships` deal exchanges it privately in the trade chat (NIP-17). |
| `g` | Geohash for pickup location |
| `location` | Human-readable pickup location |
| `a` | Reference to a skate spot (format: `30818:pubkey:d-tag`) |
diff --git a/src/components/ListingTradeActions.tsx b/src/components/ListingTradeActions.tsx
index db41b4d..668acb0 100644
--- a/src/components/ListingTradeActions.tsx
+++ b/src/components/ListingTradeActions.tsx
@@ -192,6 +192,14 @@ export function ListingTradeActions({ item }: { item: MarketplaceItem }) {
)}
+ {/* Shipped deals are the case escrow exists for — nudge it. */}
+ {canEscrow && item.fulfilment === 'ships' && (
+
+ 📦 Shipped deal — use escrow so neither side ships into the void. Share your
+ address privately in the trade chat, never here.
+
+ )}
+
{/* Buyer: ask the seller to record the sale (kind 31872 request) */}
{!canEscrow && user && !isOwnListing && isSold && !iConfirmedTrade && !sellerNamedMe && !iRequestedConfirmation && (