Agent Discoverability Score — v1 design¶
Status: design sketch, 2026-05-17. Supersedes the prior "Marketplace SEO" framing. Owner: vell-admin Predecessor doc: MARKETPLACE_SEO_SCORE.md (kept for reference; rename or retire after v1 ships)
Why we're reframing¶
There is no direct API for "Marketplace SEO." AWS Marketplace does not expose ranking signals, impression data, or agent-routing decisions. Anything called "MP SEO scoring" using only public APIs is overpromising.
What is available — and what AWS's own agent-driven discovery weights — is cross-source consistency: how closely a partner's MP listing aligns with their website, their third-party reviews (G2 / Capterra / TrustRadius), and their public search presence. Partners who score well on consistency get surfaced by AWS agents on requirement-shaped queries. Partners with 5 near-duplicate listings differentiated by industry score worse because split signals dilute consistency.
Blue-ocean insight: partners told us they update their MP listings ~4×/yr. The listing is a near-frozen artifact. Rankings, third-party reviews, and search rank shift weekly. Nobody is running a cron-driven, always-on discoverability audit for partners — that's the moat. Vellocity becomes the partner's continuous discoverability surface, not a one-time audit tool.
What we ship¶
A score (0–100) per listing, recomputed weekly via cron, with:
- A composite score rolled up from 5 sub-scores (one per signal source)
- A ranked findings list of specific cross-source mismatches
- AI-generated rewrite suggestions for each mismatch (Bedrock Sonnet 4.5)
- A trendline showing score-over-time so partners see their work paying off
The dashboard treats this as a living signal, not a one-shot audit.
Five signal sources¶
| # | Source | What we read | What we compute |
|---|---|---|---|
| 1 | AWS MP listing | Title, short desc, long desc, categories, integrations, pricing dimensions — pulled from existing marketplace_listings table or AWS MP Catalog API |
Field embeddings via Bedrock Titan; baseline consistency vector |
| 2 | Partner website | Hero <h1>, <meta name="description">, product-page H1/H2, product-page body copy. Reuse the crawler already in Cloud Connector wizard |
Embed each chunk; cosine similarity vs listing fields — flag pairs <0.65 |
| 3 | G2 | Product page: review count, rating, top-mentioned phrases, claimed categories | Are G2's categories a subset of MP's? Do top mentions match the listing's claimed value props? |
| 4 | Capterra | Same shape as G2: reviews, category tags, claimed features | Same: subset check + value-prop alignment |
| 5 | Brave + SearchAPI (search-presence proxy — replaces DataForSEO) | For each of 5 templated queries (<product> AWS marketplace, <product> alternatives, <category> AWS, <product> reviews, <product> integration), rank position of: MP listing URL, partner website, G2/Capterra |
Composite presence score 0–100 |
Pipeline architecture¶
Tables (new)¶
audit_signals
id, listing_id, signal_source (enum: mp_listing|website|g2|capterra|search_presence),
signal_payload (jsonb — raw fetched data), embedding (vector), fetched_at,
next_refresh_at -- per-source cadence (see below)
audit_findings
id, listing_id, audit_run_id, severity (high|med|low),
source_a, source_b, -- which two surfaces conflict
field_a, field_b, -- e.g. "mp_listing.short_description", "website.hero_h1"
similarity_score, suggested_rewrite (text, from Bedrock), accepted_at
audit_runs
id, listing_id, composite_score, sub_scores (jsonb), started_at, finished_at,
bedrock_tokens_used -- so we can track cost per audit
Schema is polymorphic on signal_source so adding TrustRadius / Gartner Peer Insights / Reddit later is config-only.
Cron cadence¶
| Signal | Refresh | Why |
|---|---|---|
| MP listing | Weekly | Listings barely change (4×/yr per partner survey); weekly catches it without burning rate limit |
| Partner website | Weekly | Crawl is cheap, copy occasionally changes |
| G2 / Capterra | Weekly | Reviews trickle in continuously; weekly cadence keeps trend smooth |
| Brave search-presence | Daily | Rankings shift fastest; this is the most volatile signal and the most actionable |
| Composite audit run | Weekly | Triggered after all signals refresh; produces the score + findings + rewrites |
Cron job names:
audit:refresh-mp-listings weekly Mon 02:00 UTC
audit:refresh-websites weekly Mon 03:00 UTC
audit:refresh-g2 weekly Tue 04:00 UTC
audit:refresh-capterra weekly Tue 04:30 UTC
audit:refresh-search-presence daily 05:00 UTC
audit:compute-scores weekly Wed 06:00 UTC (depends on all 5 refreshes)
audit:generate-rewrites weekly Wed 07:00 UTC (depends on compute-scores)
Service layout (rename / repurpose existing)¶
- Existing:
App\Services\DataForSEO\MarketplaceSeoScoringService— rename namespace toApp\Services\AgentDiscoverability\*(already in backlog as "rename DataForSEO namespace vendor-agnostic"). This becomes the composite-score orchestrator. - New:
App\Services\AgentDiscoverability\Signals\MpListingSignal,WebsiteSignal,G2Signal,CapterraSignal,SearchPresenceSignal— each implementsSignalSourcecontract:fetch($listing)→audit_signalsrow +embedding. - New:
App\Services\AgentDiscoverability\ConsistencyScorer— pairwise cosine similarity across signal vectors, producesaudit_findingsrows. - New:
App\Services\AgentDiscoverability\RewriteSuggester— Bedrock Sonnet 4.5 prompt: given two conflicting copy snippets, suggest a rewrite that preserves both signal intents. Stored asaudit_findings.suggested_rewrite.
Output for the partner¶
A single dashboard card per listing:
┌──────────────────────────────────────────────────────────┐
│ Agent Discoverability Score 72 / 100 │
│ ↑ +4 from last week │
│ │
│ Cross-source consistency ████████░░ 82 │
│ Search presence ██████░░░░ 61 │
│ Third-party signal alignment ███████░░░ 73 │
│ │
│ Top finding (high severity): │
│ Your MP listing says "AI-powered analytics". │
│ Your website hero says "Real-time dashboards". │
│ Your G2 reviews mention "compliance reporting". │
│ │
│ Suggested rewrite: │
│ "AI-powered compliance analytics with real-time │
│ dashboards — built for regulated industries." │
│ [ Accept ] [ Edit ] [ Dismiss ] │
└──────────────────────────────────────────────────────────┘
Each finding has a Bedrock-generated rewrite. The Accept action drafts a marketplace_listing_update_request row that the partner can push to MP via the existing publish flow. This makes the audit actionable, not just diagnostic.
What this is NOT¶
- ❌ A claim that we have AWS-internal ranking data. We don't. We measure inputs AWS's agents also consume.
- ❌ A one-shot audit. The value compounds via cron — the more weeks of trendline data, the better the story.
- ❌ A replacement for human-written listing copy. We surface mismatches and suggest rewrites; the partner decides.
Pricing fit¶
Per the 2026-05-17 capability-tier decision, MANAGE_SEO was bumped from accelerate → command_plus. That gates this whole feature to Command+ and Enterprise tiers, which matches:
- Premium framing: cron-driven, ongoing, AI-rewrite — feels like a senior-headcount-replacement at $3,999/mo Command tier
- Cost discipline: 5 sources × weekly cron × Bedrock rewrites is meaningful spend; gating to Command tiers keeps unit economics defensible until usage-based settles
- Story arc: pairs cleanly with the AWS MP agentic-payments pilot announcement — "as AWS agents drive discovery, we're the cron that keeps you discoverable"
Open questions before build¶
- Name: ~~Working title pending lock.~~ Locked 2026-05-17: "Agent Discoverability Score". Other candidates considered and rejected: Agent-Readability Audit, Agent Discoverability Audit. Use this string verbatim in marketing copy, UI labels, dashboard headers.
- G2 / Capterra scraping policy: are we OK with public-page scraping at weekly cadence, or do we want G2 / Capterra API contracts (G2 has one; Capterra is unclear)? Affects rate limit + legal posture.
- Bedrock cost ceiling per audit: rewrite generation per finding × ~5–15 findings per listing × N listings. Need a per-tenant cap (e.g., 50 rewrites per audit run) and an upgrade path.
- First-week trendline: since trendline is the story, do we backfill
audit_runswith synthetic baselines, or just ship and accept "week 1 you see your starting line, week 2 you see the delta"? Recommend the latter — honest. - Marketing copy on
/pricing: the "Marketplace SEO" string on the marketing-3pi pricing card and listing-score section needs to flip to the new name once locked. Also affectsMARKETPLACE_SEO_SCORE.md(retire or rename).
Sequencing¶
| Week | Work |
|---|---|
| W1 (this week) | Lock name. Update marketing copy on /pricing + MARKETPLACE_SEO_SCORE.md. Build audit_signals/audit_findings/audit_runs migrations |
| W2 | MpListingSignal + WebsiteSignal + ConsistencyScorer. First end-to-end with 2 sources |
| W3 | G2Signal + CapterraSignal. Cron infra (job classes, schedule registration in Console/Kernel.php) |
| W4 | SearchPresenceSignal (Brave + SearchAPI). RewriteSuggester with Bedrock |
| W5 | Dashboard card. Accept / Edit / Dismiss actions writing marketplace_listing_update_request |
| W6 | Polish + trendline chart + capability-gate enforcement |
3–4 weeks of focused work as the user picked, allowing for normal interruptions.