SHOP

SHOP

SHOP compiles the public projection aggregate. Every USER is a SHOP. Every artifact has a price.

DISCOVERY

Discovery

Pattern: {USER}/**/SHOP.md Output: SHOP.json aggregate per USER Gate: Deterministic, rerun-safe, drift-gated

PRODUCT CARD SCHEMA

Product Card Schema

```

CARD

Card

```

FieldValue
title{product name}
typeBOOKPAPERDECKCHATcontentproduct
price{amount} COIN
route/{route}/
seller{USER principal}
statusAVAILABLEBETAIN PROGRESS
synopsis{1-2 sentence description}
cover{image path or omit for gradient}
tags{comma-separated keywords}
audienceclinicaltechnicalbusinessgeneral
domainhealthcarefinancelegalrealestategovernanceengineering
author{creator name}
edition{version string: 1.0, BETA, etc.}
CHECKOUT FLOW

Checkout Flow

Purchase supports dual payment:

Stripe Checkout session metadata carries: { event, product, service, amount_coin }. Webhook on checkout.session.completed triggers vault SALE event.

MethodFlowEvent
COINAPI `/api/v1/spend` → buyer WALLET debit + seller WALLET creditSPEND + MINT:WORK
FiatAPI `/api/v1/checkout` → Stripe Checkout → webhook → SALE eventSALE via stripe-sync
COMPOSABILITY CONTRACT

Composability Contract

SHOP is a composable service. Any page includes it via frontmatter. Same pattern as TALK.

Frontmatter

Include

{% include SHOP.html %} renders from page.shop + SHOP.json. ONE include. ONE script. ONE stylesheet.

Data

SHOP.json per scope — compiled from SHOP.md Card tables. Shape: { products: [{ title, type, price, status, synopsis, route, cover, seller, tags, audience, domain, author, edition }] }

Product Card

One card. One CTA.

Element Rule
Cover Image or CSS gradient
Eyebrow Type (BOOK, PAPER, DECK, CHAT)
Title Product name
Synopsis 1-2 sentence description
Tags Comma-separated → rendered as pill chips
Badges Audience + domain badges (monospace, token-colored)
Price “{amount} COIN” or “Free”
CTA “Add to Bag” (priced) or “Get” (free). Single button.

Bag

Overlay (like TALK overlay). localStorage canonic-bag.

Element Rule
Items Title + price per item. Remove button.
Total Sum of COIN.
CTA “Checkout” — one button.
Empty “Your bag is empty.”

Checkout

Method Flow Event
COIN Confirm → /api/v1/spend → success SPEND
Card Stripe hosted → return with ?checkout=success SALE via stripe-sync

Single method selector. Not dual buttons per product.

Wallet Projection

Wallet lives in USER profile. SHOP reads WALLET.load() from base/wallet.js. Balance renders as subtle pill in SHOP header. Never reimplemented per page.

KeyValuesBehavior
shoptrueFull catalog — product grid + bag + checkout
shopinlineInline product cards only (e.g. BOOKS page)
shopfalse/omittedNo commerce UI
TALK AUTO