AWS Marketplace Self-Launch — Canonical State¶
This is the single source of truth for Vellocity launching itself on AWS Marketplace ("be my own customer first" / dogfood). It consolidates and supersedes three older docs (now deleted):
MARKETPLACE_SESSION_HANDOFF_2026_06_16.md,MARKETPLACE_LAUNCH_CLOSEOUT_PROMPT.md, andLAUNCH_SESSION_HANDOFF.md. Companion:AWS_MARKETPLACE_LAUNCH_GAP_AUDIT.md(42-point checklist gaps) andGTM_SEGMENTATION_3PI_VS_STANDALONE.md(positioning). Canonical memory:project_aws_mp_launch_readiness.Last reconciled: 2026-06-16. Paste this into a new session to continue the work.
0. TL;DR — where we actually are¶
- ✅ Stage 1 DONE & IRREVERSIBLE on the real listing. 6 contract-tier dimensions are permanently
registered on
prod-fcqhg7gqf2nxe(change-set507kmx5xsgicoth945qadf21z= SUCCEEDED). Do not re-add or rename them — AWS dimension Keys are immutable. - ✅ Billing-path CODE is real end-to-end (ResolveCustomer → GetEntitlements → BatchMeterUsage hourly → agreement sync 6h). Shipped & verified.
- ✅ VAT fix + log-only bedrock audit + pricing reconcile promoted to prod (PR #1721, squash
e797790f3; prodgateways.stripetax 8.5→0). - ✅ Listing auto-sync/import shipped to dev (
27e3a9eb6) — connecting an AWS account imports the user's real listings; both real drafts imported into the dev DB via the cross-account read role. Not yet promoted to prod (surgical squash PR pending — see §8 step 4). - ⛔ Stages 2–4 (delivery option → offer pricing/EULA → release) not started. Stage 2 is blocked by prod gap #3 (fulfillment URL behaviour on prod — fix exists on dev, not yet promoted).
- 🟠 Prod paid-path gaps — 2 of 4 now fixed ON DEV (
f8d3a2688, not yet on prod): gap #3 (fulfillment now accepts AWS's POST token + CSRF-exempt) and gap #4 (realAws\Sns\MessageValidatoron the live subscription webhook) are resolved on dev; gap #2 is de-risked (ARN mismatch warns, no longer drops notifications). Still open on prod untilf8d3a2688promotes dev→main. Gap #1 (placeholder product code) untouched. See §6. - 🟡 Founder-owned KYC (tax interview + bank/disbursement) gates creating ANY paid offer. See §7.
- 🤖 AWS now supports agent / MCP-server listings as first-class SaaS delivery options
(
ApiDeliveryOptionDetails). Full schema in §3 — separate surface from pricing dimensions.
1. Account / entity / infra map (stable)¶
| Item | Value |
|---|---|
| Marketplace seller account | 137068223442 — profile vell-marketplace-admin (SSO; admin@vell.ai assignment restored 2026-06-15). Use for start-change-set / publishing. |
| App prod+dev acct | 253265132499 (profiles vell-prod-admin / vell-dev-admin; dev 10.43.x, prod 10.42.x, demo 10.44.x) |
| Org / payer | 016156997202 (vell-mgmt-admin, vell-mgmt-billing; Identity Center instance ssoins-72233c223cfec835) |
| Catalog API region | us-east-1 only |
| Keeper listing (publishing this one) | prod-fcqhg7gqf2nxe (SaaSProduct@1.0) — "Vellocity: AI-Powered AWS Marketplace Listing and Co-Sell Automation" |
| Listing ProductCode | 2gpfhs29j2p1paoynnm0ifm2l |
| Other dogfood draft (keep, don't touch) | prod-i6z5brjwijo7i |
| Prod env SSM param | /prod/app/.env (us-east-1; siblings /dev/app/.env, /demo/app/.env) |
| Cross-account READ role (app listing-sync only) | arn:aws:iam::137068223442:role/VellMarketplaceCatalogRead (read-only Catalog; trusts app user vell-ai-s3-tenant). Cannot StartChangeSet — publishing uses vell-marketplace-admin. |
Pipelines: dev-pipeline, demo-pipeline, prod-pipeline, VellLambdaPipeline. dev-pipeline runs
migrations during CodeDeploy hooks; dev deploys are slow/flaky (~25 min, npm/vite build) but
self-complete. Listing content is already complete (long desc, 3 highlights, support tiers,
categories, logo, doc links) — no content rewrite needed.
Registration status (reconciled): the Marketplace seller account 137068223442 is Active
(Catalog API publishing works via vell-marketplace-admin). Partner Central / ACE co-sell
registration is separate and still gates checklist #29 (ACE), #33 (co-sell), #35 (ISV Accelerate) —
Partner Central selling API is reachable but shows 0 engagements and Catalog partnercentral
calls return AccessDenied until ACE registration completes.
2. Locked decisions (DO NOT re-debate)¶
- Pricing = Starter $299 / Accelerate $1,499 / Command $3,999 /mo ($2,990 / $14,990 / $39,990 /yr).
DB
planstable is source of truth. Express rate-cards ($179/$349/$899) = separate private-offer channel — leave alone. - Enterprise = Request-a-Private-Offer CTA (ACE / AWS Demand-Gen co-sell PLG), not public
dimensions (a public offer can't carry a "contact-us" price).
MktplEnterpriseMonthly/Yearlyexist in config but were intentionally not registered. - EULA = AWS Standard Contract (SCMP) — host nothing. NO custom/self-hosted EULA, NO S3/CloudFront
for launch. (
Type:"StandardEula",Version:"2022-07-14".) - Submission route = Catalog API change-sets via
vell-marketplace-admin, staged, HITL before Release. - Scope rule: Vellocity assists GTM once a listing exists. Identity/legal/financial onboarding
(registration / KYC / tax / banking / EULA-legal / Release) is out of scope — detect-and-guide,
or a Ron service, never a software feature. Write explicit "out of scope" callouts in any
spec/prompt. This session's dimension/offer work is founder-by-hand, NOT customer-replicable
(customer cross-account role is read-only; the app only writes content via
UpdateInformation).
3. ✅ DIMENSIONS BUILT (Stage 1 — irreversible, do not redo)¶
Change-set 507kmx5xsgicoth945qadf21z = SUCCEEDED (AddDimensions on prod-fcqhg7gqf2nxe).
Verified via DescribeEntity: all present, all Entitled.
| Dimension Key (PERMANENT) | Display Name | Types | Unit | Monthly $ | Annual $ |
|---|---|---|---|---|---|
MktplStarterMonthly |
Marketplace Starter (Monthly) | ["Entitled"] |
Units | $299 | — |
MktplStarterYearly |
Marketplace Starter (Annual) | ["Entitled"] |
Units | — | $2,990 |
MktplAccelerateMonthly |
Marketplace Accelerate (Monthly) | ["Entitled"] |
Units | $1,499 | — |
MktplAccelerateYearly |
Marketplace Accelerate (Annual) | ["Entitled"] |
Units | — | $14,990 |
MktplCommandPlusMonthly |
Marketplace Command+ (Monthly) | ["Entitled"] |
Units | $3,999 | — |
MktplCommandPlusYearly |
Marketplace Command+ (Annual) | ["Entitled"] |
Units | — | $39,990 |
- Keys match
config/services.phpplan_mappingexactly →MarketplaceEntitlementServicedimension→plan mapping works as-is. Never rename (immutable Keys; rename = new dimension + broken mapping). - Prices are NOT on the dimensions — they go on the offer (
ConfigurableUpfrontPricingTermrate cards) in Stage 3. Dimensions only declare the entitlement facets. - Pricing-model lock: the first
AddDimensionsfixes the product's pricing model. All 6 areEntitled(contract). Adding usage/metering dims later (Metered/ExternallyMetered) is a different model → requires AWS Marketplace Seller Operations, not a self-serve change-set. Unitenum: Users, Hosts, GB, MB, TB, Gbps, Mbps, Requests, Units, UserHrs, UnitHrs, HostHrs, TierHrs, TaskHrs.Typesenum:Entitled,Metered,ExternallyMetered.
Metered/usage dims — defined in config, NOT yet on the listing¶
config/services.php usage_dimensions (7): Words, Images, AudioMinutes, VideoMinutes,
APIRequests, Presentations, SEOCredits → map to MarketplaceUsageRecord::DIMENSION_*, metered
via BatchMeterUsage. Adding them = Metered/ExternallyMetered = different pricing model → AWS
Seller Ops required. Recommendation: launch Contract-only; add metered dims when overage billing
is actually exercised. Decide Contract vs Contract-with-Consumption before involving Seller Ops.
4. 🤖 AGENT / MCP LISTING DELIVERY (new AWS capability — the wedge)¶
For agent listings the "agent-ness" lives in the delivery option, not the pricing dimension. AWS
added a first-class ApiDeliveryOptionDetails delivery type to SaaSProduct@1.0.
Change types: AddDeliveryOptions, UpdateDeliveryOptions, UpdateDeliveryOptionsVisibility. Two
delivery detail types:
- SaaSUrlDeliveryOptionDetails — traditional web SaaS (← Vellocity's own listing uses this).
- ApiDeliveryOptionDetails — agent / API products (the new agent-readiness surface).
ApiDeliveryOptionDetails schema¶
| Field | Req | Notes / enum |
|---|---|---|
ApiType |
✔ | MCP_SERVER · KNOWLEDGE_BASE · AGENT · GUARDRAIL · OTHER |
QuickLaunchEnabled |
✔ | bool |
FulfillmentUrl |
✔ | https, must render HTTP 200 (AWS probes it) |
UsageInstructions |
✔ | markdown, ≤ 30,000 chars |
CompatibleServices |
— | currently only Bedrock-AgentCore |
Endpoints |
✔ | exactly 1 endpoint |
└ Name |
— | regex ^[A-Za-z][a-zA-Z0-9-]+$, ≤100 |
└ EndpointUrl |
✔ | https, must render 200 |
└ Description |
— | ≤4,000 |
└ AuthorizationTypes |
✔ | 1–2 of API_KEY · OAUTH2 |
└ Schemas |
— | max 1: Type:"OPEN_API", SchemaUrl must point to a Marketplace-owned S3 bucket (ingested asset) |
└ IntegrationProtocols |
— | max 2: Type: MCP · A2A, UsageInstructions ≤30k |
Visibility / safe rollout (ALL delivery options incl. SaaSUrl)¶
UpdateDeliveryOptionsVisibility:TargetVisibility ∈ {Limited, Public, Unavailable}.- Exactly one
Public; max oneLimited. Limited+Targeting.PositiveTargeting.BuyerAccounts[](≤100) = test the offer against your own buyer account before going Public — the clean path for the $1 self-test (B3).- SaaS "Free" pricing still requires ≥1 dimension priced $0.00 (prices as
"0.00"strings).
Strategic read: AWS is making listings agent-retrievable (AGENT/MCP_SERVER, Bedrock-AgentCore,
MCP/A2A, OpenAPI ingestion) + shipped a public Discovery API (Apr 2026) — the under-served
agent-readiness lane (timing edge vs Tackle/Suger). Two productizable surfaces: (a) Vellocity
publishes its OWN agent/MCP listing; (b) Vellocity generates customers' ApiDeliveryOptionDetails +
MCP/A2A + OpenAPI schema as a feature (HITL before release). See project_aws_mp_track_b_agent_listing.
5. Remaining change-set stages (not started)¶
Only Stage 4 is irreversible / outward-facing. Failed change-sets are non-destructive.
| Stage | ChangeType(s) | Entity | Notes |
|---|---|---|---|
| 2 | AddDeliveryOptions → SaaSUrlDeliveryOptionDetails |
SaaSProduct | FulfillmentUrl=https://vell.ai/marketplace/register. Blocked by gap #3 (URL 302s on prod). After success, DescribeEntity for the do-… delivery-option ID. |
| 3 | UpdatePricingTerms (ConfigurableUpfrontPricingTerm rate cards) + UpdateLegalTerms (StandardEula) + UpdateAvailability |
Offer (auto-created draft, appears in publish flow) | Rate cards key off the 6 dimension Keys. EULA Type:"StandardEula", Version:"2022-07-14" (matches MarketplaceCatalogPublishService::buildLegalTermsChange). |
| 4 | ReleaseProduct (empty DetailsDocument) + ReleaseOffer |
Product + Offer | For SaaSProduct@1.0, ReleaseProduct must be paired with ReleaseOffer on the draft public Offer. Moves product → Limited → public after AWS review. PAUSE for explicit approval. |
6. 🟠 PROD PAID-PATH GAPS (block a working B3 test txn)¶
Engine code is REAL; prod wiring is placeholder/demo. None block Stage 1 (already done).
Update 6/16: gaps #3 + #4 are fixed on dev (f8d3a2688, NOT yet on prod); gap #2 de-risked by
the same commit; gap #1 still open. Promote f8d3a2688 dev→main to close #3/#4 on prod.
| # | Gap | Status | Evidence | Fix |
|---|---|---|---|---|
| 1 | Product code is a placeholder | 🔴 OPEN | /prod/app/.env → AWS_MARKETPLACE_PRODUCT_CODE=vell-product-code |
Set to 2gpfhs29j2p1paoynnm0ifm2l. Edit SSM /prod/app/.env source only — let the refresh cron re-merge; never overwrite the instance blob. |
| 2 | SNS topic = demo-leads topic | 🟡 De-risked | AWS_MARKETPLACE_SNS_TOPIC_ARN=…:vell-prod-marketplace-demo-leads |
After the offer publishes, AWS auto-creates the SaaS subscription topic — set that ARN. No longer a hard blocker: f8d3a2688 made topic-ARN mismatch a logged warning (signature is authoritative), so a stale ARN won't drop real notifications. |
| 3 | Fulfillment URL behaviour | 🟢 Fixed on dev (f8d3a2688) |
Was: prod bare GET /marketplace/register → 302→/login. f8d3a2688 makes the route public match(['get','post']), reads the token from query or POST body (AWS POSTs it on subscribe), CSRF-exempts /marketplace/register, and moves the account form to register/complete. |
Promote f8d3a2688 dev→main (surgical squash). Until then prod still 302s and Stage 2 risks async INVALID_FULFILLMENT_URL. |
| 4 | Live subscription webhook sig check | 🟢 Fixed on dev (f8d3a2688) |
Was: MarketplaceSubscriptionController::verifySnsSignature matched topic-ARN only + had a return !$expectedTopicArn dev bypass. f8d3a2688 replaces it with real Aws\Sns\Message + MessageValidator()->validate() (rejects on failure; bypass removed). |
Promote f8d3a2688 dev→main before real $ flows. ⚠️ Earlier docs/memory's "SNS sig-validated" claim was true only for the demo path until this commit. |
Minor bug seed: MarketplaceSubscriptionController::createSubscriptionForUser() writes
stripe_price => $plan->price_monthly even for yearly entitlements.
7. Founder-owned KYC — can't automate (Partner Central console)¶
These gate the paid offer; the agent cannot and must not do them — identity/financial. 1. Complete tax interview (Required). 2. Set up bank account / disbursement (Required) — explicitly gates creating ANY paid offer or public listing. Must be done before Stage 3. 3. IAM access guidance — add 2 Partner Central users (backup access). 4. Verify Identity for EMEA/APJ — optional, defer.
8. Next actions (dependency order)¶
- Promote
f8d3a2688dev→main — closes gaps #3 (fulfillment POST/CSRF) and #4 (real SNSMessageValidator) on prod in one surgical squash. Then set gap #1 product code in SSM/prod/app/.env. (Fetch + check churn first — a concurrent session pushes to dev/main.) - Confirm
https://vell.ai/marketplace/registerreturns 200 bare (GET) and accepts AWS's POST token. - Confirm founder KYC §7.1 (tax) + §7.2 (bank/disbursement) are done in Partner Central — these gate Stage 3. If not, guide the founder through exactly what they require.
- Promote listing-sync feature
27e3a9eb6dev→main — surgical squash PR (repo blocks merge-commits); do NOT sweep unrelated dev commits; fetch/diff/categorize/pause first; verify on prod read-only after. - Close the dogfood loop: connect seller acct
137068223442inside the app (cloud-connector flow or insert acloud_connectionsrow usingVellMarketplaceCatalogRead) →SyncListingsJobimports the 2 real drafts → Listing Optimizer / Discovery / Alignment Grader score the REAL listings. - Stage 2
AddDeliveryOptions(SaaSUrl) →DescribeEntityfordo-…id + the auto-created Offer id. - Stage 3 offer pricing + StandardEula + availability.
- Decide Contract vs Contract-with-Consumption (§3 metered note) before any metered dims / Seller Ops.
- Use
Limitedvisibility + your own buyer account for the $1 self-test (B3, checklist #28); fix gap #2 (SNS topic) + gap #4 (sig validation) before/at that point. - Stage 4
ReleaseProduct+ReleaseOffer— PAUSE for explicit approval (goes public). - Partner Central / ACE registration on
137068223442to unblock #29 / #33 / #35.
9. Guardrails / hard-won lessons¶
- Never manually overwrite a remote instance
.env— it's assembled from multiple SSM sources (/<env>/app/.envblob + DB creds merged from/<env>/db/secretby the refresh-secrets cron). Fix a secret by editing the SSM source only and letting the cron re-merge. (A raw-blob overwrite dropped the DB password → brief dev 503.) - Prod verification is read-only — SSM
select-only tinker; no manual prod writes/.env edits. - dev→main = squash only (merge-commits blocked); pause for approval before promoting; a concurrent session pushes to dev/main frequently — always fetch + check for conflicts/churn first.
- Work app code in
code/social(dev); stage only your own files (nevergit add -A); the working tree carries ~2,270 unrelated dirty node_modules files. - Dev may sit at 2 instances (zero-downtime deploys) — revert to 1 with
aws autoscaling update-auto-scaling-group --auto-scaling-group-name dev-compute-AutoScalingGroup-62fpuHh1IuSH --min-size 1 --desired-capacity 1once the push settles.
10. Adjacent prompts (separate sessions, already written)¶
docs/marketing/DESIGN_PARTNER_SPRINT_PROMPT.md— 5–10 design partners / consulting clients in 14 days.docs/DOCS_VELL_AI_REFRESH_PROMPT.md— docs.vell.ai cleanup to current capabilities.