Sentinel Signal

MCP Verify — Product architecture gap-assessment, Track 2 Phase 2 implementation

Source: docs/mcp-verify-product-architecture-track2-phase2-implementation.md

Document Content

MCP Verify — Product architecture gap-assessment, Track 2 Phase 2 implementation

Target release: 1.0.537.

Source: Track 2 of the section-55 gap assessment against "Verify — Product Architecture & Development Plan," scoped per the user's explicit answers to four questions asked before starting:

  • Registry//search split: **new /search route** (recommended) — but
  • deferred to a follow-up pass (see below).

  • Methodology split: full 3-way split (recommended) — deferred.
  • Pricing restructuring: leave both dedicated pricing pages as-is,
  • just fix the unexplained Pro range — implemented this round.

  • Session scope: start with low-risk phases now (homepage narrative +
  • evidence-wording audit), defer registry/methodology/pricing-restructure work needing new routes or IA decisions to separate follow-up rounds.

Implemented changes

  • Homepage hero rewrite (doc §7-8, H1-H3): replaced the category-first
  • headline ("MCP TrustOps for agent tool execution") with the doc's own suggested outcome-first copy: "Know which MCP servers your agents can use — and enforce the decision." Hierarchy now matches the doc's required order: outcome (h1) → how (supporting paragraph) → TrustOps category label → CTA row. The CTA row was cut from two CTAs whose labels didn't match the doc ("Scan my server" / "Browse strong candidates") to the doc's specified two-primary-plus-one-secondary set: "Search MCP servers" (anchors to the existing inline search form via #search-mcp-servers — no new route needed since the registry/search split is deferred), "Explore TrustOps" (/trustops), "Claim your server" (/claim). "Scan my server" wasn't deleted — it's still reachable from the existing secondary-links footer (render_site_secondary_links), where it already lived.

  • **Discover → Verify → Decide → Enforce → Prove lifecycle section (doc
  • §9)**: new render_platform_lifecycle_section() (main.py), a pure addition — five cards (Discover/Verify/Decide/Enforce/Prove), each with the doc's own one-line explanation and a link to the closest existing route for that stage. Inserted directly after the hero CTA row, before the coverage-funnel panel, matching the doc's target homepage information architecture (§50: Hero → Lifecycle → Evidence Funnel → Search → ...). This concept had no homepage presence at all before this change.

  • Coverage funnel product-thesis sentence (doc §10, C2): the funnel
  • itself was already correctly implemented as a connected strict-subset progression (confirmed in the original gap assessment). Added the one missing piece: a sentence framing the large-inventory-vs-small-validated gap as the product thesis ("Public MCP inventory is enormous. Only a small portion currently produces fresh evidence suitable for governed adoption — that narrowing is the problem Verify exists to solve, not a gap in coverage.") directly above the funnel cards.

  • Pro pricing clarity (doc §31): /pricing's Pro tier showed a bare
  • $99-499/month with no explanation. Investigated where the range actually comes from: it exactly spans two tiers (render_verify_intelligence_api_page's own "Suggested pricing" table) — Startup ($99/month) and Team ($499/month), differentiated by API call volume, historical diffs, evidence packs, webhooks, and commercial-use rights. Changed the main pricing card to "From $99/month" plus a sentence naming those real scaling dimensions and linking to the full tier table, rather than inventing new pricing mechanics not backed by the actual product.

  • Evidence-wording re-audit, one real fix found (doc §18/§49, Phase 6):
  • re-swept the codebase for "absence phrased as evidence" patterns beyond the one Track 1 already fixed. Found snapshot_churn_risk (build_client_readiness_verdicts, insights.py): build_tool_snapshot_diff returns None specifically when there is no previous validation to compare against at all — a genuine "compared, nothing changed" result always returns a dict with snapshot_changed: False. The verdict's status/reason previously collapsed both cases to "low" / "No material tool-surface churn detected in the latest comparison," a false claim that a comparison happened when, in the None case, it never did. Now reads "not_assessed" / "No prior validation is available to compare against yet — churn risk has not been assessed." render_risk_badge (main.py) already renders any unrecognized status as a neutral "Unknown" chip, so no render-layer change was needed beyond the value itself.

Investigated, not fixed — recorded for a future pass

  • advanced_capabilities_probe's "No advanced MCP capability signals
  • detected." (main.py): unlike the two bugs above, this probe's own underlying data does not currently distinguish "confirmed zero advanced capabilities" from "the checks that would reveal them never ran" — build_advanced_capabilities_probe (validation/service.py) computes capability flags unconditionally from whatever checks/ metadata_documents/current_tools happen to be available, with no is_core_success_from_check_results-style guard. Fixing the display text alone would require inventing new not-assessed detection in the probe itself — a different, larger scope of work than reading an already-existing signal correctly (which is what both fixes above did). Deferred rather than adding unevidenced new probe logic in the same pass as a display-wording fix.

Deliberately deferred (per the session's own scope decision)

  • Registry//search route split (doc §12) — the homepage's search box now
  • anchors to the existing inline form; the full 13-filter registry still lives on /, not a separate route.

  • Methodology 3-way page split (doc §25-28).
  • Pricing restructuring — Publisher (/verified-server-profile) and
  • Intelligence API (/verify-intelligence-api) remain fully independent pricing ladders, per the explicit "leave both pages as-is" decision.

  • Everything else in the doc's Phase 3 (funnel — already implemented),
  • Phase 5 (server-profile tier regrouping), Phase 9 (analytics rename/ /manage correlation), Phase 10 (compare-telemetry aggregation).

Validation

  • PYTHONPATH=verify/src pytest verify/tests -q — 491 passed (up from
  • 487): 9 new/extended, including a parametrized test proving snapshot_churn_risk distinguishes all three real cases (no baseline / confirmed unchanged / confirmed changed), and an end-to-end homepage test asserting the outcome → how → category → CTA hierarchy by string index, not just presence.

  • python3 scripts/export_openapi.py --check — fresh after regenerating
  • against v1.0.537 (no response-schema changes; the one API-visible value change, snapshot_churn_risk.status gaining a new possible string, is not schema-enforced).

  • Root-repo pytest (app/token_service, run by the pre-commit hook) —
  • 188 passed, unaffected; no files outside verify/, docs/, openapi/openapi.json, and version-artifact files touched.