Skip to content

GTM Studio Product Clarity: First Call Deck vs AI Presentation

Date: 2026-03-08 Context: Aligns to PARTNER_OUTPUT_PORTABILITY_AUDIT.md Status: Product strategy recommendation — pending decision


The Problem

Two menu items point to what is architecturally the same engine:

Route Nav Label What It Does
/dashboard/user/first-call-deck First Call Deck Wizard: company name/URL → internet enrichment → 8-slide deck
/dashboard/user/ai-presentation AI Presentation Template picker: 17+ templates → fill form → multi-format GTM content

Both generate GTM content via the same pipeline (GtmContentSchema, AWS Bedrock Claude, ContentFormatter). First Call Deck is literally FirstCallDeckTemplate extending PresentationTemplate inside the AiPresentation extension.

A user asking "Where do I input what I'm trying to sell to a company?" could reasonably go to either place. That's the clarity failure.


Current Architecture (Fact)

app/Extensions/AiPresentation/
├── System/
│   ├── Templates/
│   │   ├── PresentationTemplate.php          ← abstract base
│   │   ├── FirstCallDeckTemplate.php         ← FCD is ONE template
│   │   ├── AwsMarketplaceListingTemplate.php
│   │   ├── ValuePropositionTemplate.php
│   │   ├── CoSellBriefTemplate.php
│   │   └── ... (17 total)
│   ├── Schema/
│   │   ├── GtmContentSchema.php              ← shared output schema (v1.2)
│   │   └── FirstCallEnrichmentSchema.php     ← enrichment-specific schema (v1.0)
│   ├── Services/
│   │   ├── FirstCallEnrichmentService.php    ← web scrape → Claude synthesis
│   │   ├── ContentFirstGenerationService.php ← shared generation
│   │   ├── ContentFormatter.php              ← shared output (MD, HTML, PDF)
│   │   ├── DryRunService.php                 ← shared dry-run
│   │   └── ...
│   └── Http/Controllers/
│       ├── AiPresentationController.php      ← handles both FCD + templates
│       └── AbTestingController.php           ← A/B testing for listings
├── Livewire/
│   └── FirstCallDeckWizard.php               ← dedicated wizard UI

Key insight: FCD adds exactly ONE unique capability — the internet enrichment pipeline (FirstCallEnrichmentService + Serper API). Everything else (generation, output formats, dry-runs, gallery) is shared infrastructure.


The Overlap Matrix

Capability First Call Deck GTM Studio Verdict
Internet enrichment (company research) Yes No FCD's only unique feature
AI content generation Yes Yes Same engine
Multi-format output (MD, HTML, PDF, PPTX) Yes Yes Same ContentFormatter
Dry-run buyer personas No Yes GTM Studio only
A/B testing No Yes GTM Studio only
Gallery / asset management No Yes GTM Studio only
Deck upload + analysis No Yes GTM Studio only
Brand voice integration Yes Yes Same BrandContextBuilder
MCP/Agent readiness A/A A/A Both via schemas
Pre-onboarding (no KB required) Yes Yes* *Content-first mode works without KB too

Conclusion: FCD is a specialized entry point, not a separate product. The enrichment pipeline is the differentiator — but it's currently locked to one template instead of being available to all 17.


Recommendation: Merge Into Unified GTM Studio

Single entry point: /dashboard/user/ai-presentation

GTM Studio
├── Research Mode  ← absorbs FCD wizard
│   "I have a target company. Research them, then help me prepare."
│   Input: company name/URL + what you're selling + call objective
│   Output: enrichment dossier + template of your choice (not just 8-slide deck)
├── Create Mode  ← current template picker
│   "I know what I need. Generate it."
│   Input: template selection + your content
│   Output: presentation / brief / listing content
├── Test Mode  ← current A/B testing
│   "I have content. Help me optimize it."
└── Practice Mode  ← current dry-runs
    "I have a deck. Simulate the buyer conversation."

What changes:

  1. Enrichment becomes a pre-step available to ANY template — not just FCD's 8-slide deck
  2. FCD route redirects to GTM Studio Research Mode
  3. "First Call Deck" remains as a template name (it's a valid content type, like "Co-Sell Brief")
  4. Single nav item instead of two

What stays:

  • All existing schemas (GtmContentSchema, FirstCallEnrichmentSchema) — unchanged
  • All existing services — unchanged
  • Portability grades — unchanged (both already A/A)
  • MCP tool surface — simplified (one namespace)

The "easy to spread" pitch:

"GTM Studio: Research any company, generate your pitch, practice with AI buyers, then A/B test what works."

One sentence. Four modes. No confusion about which menu item to click.


Portability Audit Alignment

Per PARTNER_OUTPUT_PORTABILITY_AUDIT.md:

Audit Item Current Grade Impact of Merge
#1 GTM Content Schema A/A Unchanged — still the output schema
#4 First Call Enrichment A/A Expanded — enrichment available to all templates
#7 A/B Testing Results A/A Unchanged
#8 MCP Tool Outputs A+/A+ Simplified — one tool namespace instead of two entry points

The merge strengthens the portability story by making enrichment a composable capability rather than a siloed feature.


New Ideas — Implementation Specs

Idea 1: Partner Sales Readiness (A/B + Dry-Run Scoring)

Current state: A/B testing exists for marketplace listing content. Dry-runs exist for simulating buyer Q&A.

Proposed: Combine them — generate two versions of a pitch, run both through dry-run AI personas, score each version on how well it handles buyer objections.

Gamification angle: Score sellers on their ability to respond to AI buyer personas. Leaderboard. Certification-style badges. This opens a new product wedge:

"Partner Sales Readiness" — when partners onboard new employees, those employees practice against AI buyers tuned to specific industries before they ever get on a real call.

Novel? Yes. Sales enablement tools exist (Gong, Chorus) but they analyze AFTER real calls. This is pre-call simulation with scoring — practice mode, not post-mortem. The gamification + scoring makes it measurable and spreadable.

Market signal: Partners are increasingly hiring based on demonstrated ability (public GitHub repos for engineers). For alliance managers and pre-sales people, a scored dry-run portfolio could serve the same function — proof of preparation ability rather than resume fluff.

1.1 Scoring Rubric Schema

// app/Extensions/AiPresentation/System/Schema/ReadinessScoreSchema.php

class ReadinessScoreSchema
{
    public string $version = '1.0';

    // Per-question scoring (generated by Claude after each dry-run response)
    public array $question_scores = [
        [
            'question_id'       => 'string',           // UUID
            'persona'           => 'string',           // e.g. 'budget_holder'
            'industry'          => 'string',           // e.g. 'financial_services'
            'question_text'     => 'string',
            'user_response'     => 'string',           // what the seller typed/said
            'scores' => [
                'relevance'     => 'int (1-5)',        // did the answer address the question?
                'specificity'   => 'int (1-5)',        // concrete details vs hand-waving
                'objection_handling' => 'int (1-5)',   // addressed underlying concern?
                'cultural_fluency'   => 'int (1-5)',   // used appropriate terminology? (ties to Idea 2)
                'confidence'    => 'int (1-5)',        // tone: assertive without overselling
            ],
            'feedback'          => 'string',           // Claude-generated coaching note
            'improvement_hint'  => 'string',           // one specific thing to try differently
        ]
    ];

    // Aggregate session score
    public array $session_summary = [
        'overall_score'         => 'int (0-100)',      // weighted composite
        'persona_breakdown'     => 'array',            // score per persona tested
        'strongest_area'        => 'string',           // e.g. 'objection_handling'
        'weakest_area'          => 'string',           // e.g. 'specificity'
        'improvement_vs_last'   => 'float|null',       // % change from previous attempt
        'readiness_tier'        => 'string',           // novice | prepared | proficient | expert
    ];

    // Weights (configurable per org)
    public array $weights = [
        'relevance'             => 0.25,
        'specificity'           => 0.20,
        'objection_handling'    => 0.25,
        'cultural_fluency'      => 0.15,
        'confidence'            => 0.15,
    ];
}

1.2 Database Schema

-- Readiness sessions (one per practice attempt)
CREATE TABLE readiness_sessions (
    id              BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    user_id         BIGINT UNSIGNED NOT NULL,
    company_id      BIGINT UNSIGNED NULL,          -- optional org context
    presentation_id BIGINT UNSIGNED NULL,          -- linked AiPresentation
    variant_label   VARCHAR(50) NULL,              -- 'A' or 'B' for A/B scoring
    persona_ids     JSON NOT NULL,                 -- which personas were used
    industry        VARCHAR(100) NULL,
    company_type    VARCHAR(50) NULL,
    revenue_tier    VARCHAR(50) NULL,
    culture_pack_id BIGINT UNSIGNED NULL,          -- ties to Idea 2
    overall_score   TINYINT UNSIGNED NULL,         -- 0-100
    readiness_tier  VARCHAR(20) NULL,
    score_breakdown JSON NULL,                     -- full ReadinessScoreSchema
    started_at      TIMESTAMP NOT NULL,
    completed_at    TIMESTAMP NULL,
    created_at      TIMESTAMP,
    updated_at      TIMESTAMP,
    INDEX idx_user_score (user_id, overall_score),
    INDEX idx_user_date  (user_id, completed_at),
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);

-- Per-question scores (for drill-down analytics)
CREATE TABLE readiness_question_scores (
    id              BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    session_id      BIGINT UNSIGNED NOT NULL,
    question_id     CHAR(36) NOT NULL,             -- UUID
    persona         VARCHAR(50) NOT NULL,
    question_text   TEXT NOT NULL,
    user_response   TEXT NULL,
    relevance       TINYINT UNSIGNED NOT NULL,
    specificity     TINYINT UNSIGNED NOT NULL,
    objection_handling TINYINT UNSIGNED NOT NULL,
    cultural_fluency   TINYINT UNSIGNED NOT NULL,
    confidence      TINYINT UNSIGNED NOT NULL,
    composite_score TINYINT UNSIGNED NOT NULL,     -- weighted single score
    feedback        TEXT NULL,
    improvement_hint TEXT NULL,
    created_at      TIMESTAMP,
    FOREIGN KEY (session_id) REFERENCES readiness_sessions(id) ON DELETE CASCADE
);

-- Badges / certifications
CREATE TABLE readiness_badges (
    id              BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    user_id         BIGINT UNSIGNED NOT NULL,
    badge_type      VARCHAR(50) NOT NULL,          -- 'first_session', 'proficient_financial', etc.
    badge_label     VARCHAR(100) NOT NULL,
    earned_at       TIMESTAMP NOT NULL,
    session_id      BIGINT UNSIGNED NULL,
    metadata        JSON NULL,                     -- criteria snapshot
    created_at      TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);

-- Leaderboard view (materialized or computed)
-- Aggregates: user_id, avg_score, total_sessions, best_tier, badges_count

1.3 Service Architecture

app/Extensions/AiPresentation/System/Services/
├── ReadinessService.php              ← orchestrator
│   ├── startSession()                 - create session, select personas
│   ├── scoreResponse()                - score a single Q&A via Claude
│   ├── completeSession()              - aggregate scores, assign tier
│   ├── compareVariants()              - A/B: which variant scored better?
│   └── getImprovementTrack()          - score history over time
├── ReadinessScoringEngine.php        ← scoring logic
│   ├── scoreQuestion()                - per-question rubric evaluation
│   ├── aggregateSession()             - weighted composite
│   ├── determineTier()                - novice/prepared/proficient/expert
│   └── generateFeedback()             - coaching notes via Claude
├── ReadinessBadgeService.php         ← gamification
│   ├── evaluateBadges()               - check if session triggers any badges
│   ├── getBadgeDefinitions()          - static badge catalog
│   └── getUserBadges()                - earned badges for user
└── ReadinessReportService.php        ← export
    ├── generateReport()               - PDF/JSON readiness report
    ├── getLeaderboard()               - org-wide rankings
    └── exportPortfolio()              - shareable "readiness portfolio"

Scoring prompt strategy: After each user response in dry-run mode, send a scoring prompt to Claude:

You are evaluating a sales professional's response to a simulated buyer question.

Buyer Persona: {persona_name} — {persona_description}
Industry: {industry} with context: {industry_overlay}
Company Culture: {culture_pack if available}

Question asked: "{question_text}"
Seller's response: "{user_response}"

Score each dimension 1-5:
- relevance: Did the answer directly address the question?
- specificity: Were concrete details, numbers, or examples provided?
- objection_handling: Was the underlying concern acknowledged and addressed?
- cultural_fluency: Did the response use appropriate terminology for this buyer's context?
- confidence: Was the tone appropriately assertive without overselling?

Return JSON with scores, a 1-sentence feedback note, and a 1-sentence improvement hint.

1.4 A/B Variant Comparison Flow

User generates Pitch A and Pitch B (via Create Mode or manually)
Practice Mode: run dry-run for Pitch A against 3 personas
        │ scores: [82, 74, 88] → avg 81.3
Practice Mode: run dry-run for Pitch B against same 3 personas
        │ scores: [90, 85, 79] → avg 84.7
Comparison report:
  - Pitch B scores 4.2% higher overall
  - Pitch B stronger on objection_handling (+12%)
  - Pitch A stronger on specificity (+6%)
  - Recommendation: Use Pitch B, but incorporate Pitch A's
    specific data points for the Technical Lead persona

1.5 Badge Catalog (v1)

Badge Criteria Icon
First Steps Complete first practice session tabler-rocket
Consistent Performer Score 70+ on 5 consecutive sessions tabler-chart-line
Objection Slayer Score 5/5 on objection_handling for 3+ questions in one session tabler-shield-check
Industry Expert: Score 85+ in a specific industry 3 times tabler-building-bank
Culture Chameleon Score 4+ on cultural_fluency across 3 different culture packs tabler-language
Proficient Seller Reach "proficient" tier tabler-certificate
Expert Seller Reach "expert" tier tabler-trophy
A/B Champion Run 5 A/B variant comparisons tabler-ab-2
Speed Learner Improve score by 20+ points within 3 sessions tabler-trending-up

Idea 2: Company Culture as a Persona Trait

Current state: DryRunService supports 5 buyer personas, 9 industries, 9 AI business types, 4 company types, 6 revenue tiers. IndustryPersonaContext adds industry-specific behavioral overlays (decision_culture, hidden_concerns, procurement_dynamics, etc.).

Proposed: Add company-specific cultural vocabulary as a persona modifier. Not generic industry traits — actual company-specific communication patterns.

Examples from lived experience:

Company Cultural Vocabulary Communication Pattern
AWS LPs (Leadership Principles), WBRs (Weekly Business Reviews), MBRs (Monthly Business Reviews), EBCs (Executive Briefing Centers), mechanisms, tenets, 6-pagers, PR/FAQ Data-driven, customer-obsessed framing, "working backwards"
Accenture SOWs, "let there be change," capability leads, diamond-level, new applied now Consulting-speak, transformation narrative, stakeholder alignment
Bank of America responsible growth, eight lines of business, operational excellence Risk-aware, compliance-first, measured language
Wells Fargo team member (not employee), control environment, enterprise risk Post-crisis careful, governance-heavy
Walmart EDLP (everyday low prices), merchant mindset, Sam's rules Cost-conscious, direct, scale-focused
Air Force OPRs, EPRs, mission-first, wingman culture, OODA loop Hierarchical, mission-outcome framing, brief/debrief cadence

2.1 CompanyCultureContext Class

// app/Extensions/AiPresentation/System/Context/CompanyCultureContext.php

class CompanyCultureContext
{
    /**
     * Structure mirrors IndustryPersonaContext but is company-specific.
     * Each pack is a self-contained profile that modifies persona behavior.
     */
    public static function getCulturePack(string $companySlug): ?array
    {
        return self::CULTURE_PACKS[$companySlug] ?? null;
    }

    public static function getAllPacks(): array
    {
        return self::CULTURE_PACKS;
    }

    public static function getPacksByCategory(string $category): array
    {
        return array_filter(self::CULTURE_PACKS, fn($p) => $p['category'] === $category);
    }

    private const CULTURE_PACKS = [
        'aws' => [
            'company_name'      => 'Amazon Web Services',
            'category'          => 'hyperscaler',
            'vocabulary' => [
                'LP'   => 'Leadership Principle — one of 16 cultural tenets',
                'WBR'  => 'Weekly Business Review — operational metrics cadence',
                'MBR'  => 'Monthly Business Review — strategic review',
                'EBC'  => 'Executive Briefing Center — customer/partner presentations',
                '6-pager'    => 'Narrative document format (no slides for internal meetings)',
                'PR/FAQ'     => 'Press Release / FAQ format for new initiatives',
                'mechanism'  => 'A repeatable process with a forcing function',
                'tenet'      => 'A guiding principle for a team or initiative',
                'bar raiser' => 'Senior evaluator in hiring process',
                'working backwards' => 'Start from customer need, reason backward to solution',
            ],
            'communication_norms' => [
                'Data over anecdotes — every claim needs a metric',
                'Customer obsession framing: start with the customer problem',
                'Disagree and commit — voice concerns, then align',
                'Bias for action — propose experiments, not studies',
                'Meetings start with silent reading of a 6-pager (no pre-reads)',
            ],
            'decision_pattern'  => 'Data-driven, LP-referenced, customer-backwards',
            'meeting_culture'   => '6-pager silent reads, WBR cadence, action items with owners',
            'red_flags' => [
                'Using slides in internal meetings (perceived as hiding behind bullet points)',
                'Saying "best practice" (AWS prefers "mechanisms" and context-specific solutions)',
                'Vague ROI claims without supporting data',
            ],
            'power_phrases' => [
                'We built a mechanism for...',
                'Working backwards from the customer...',
                'The data shows...',
                'Our tenet here is...',
            ],
        ],
        'accenture' => [
            'company_name'      => 'Accenture',
            'category'          => 'consulting',
            'vocabulary' => [
                'SOW'     => 'Statement of Work',
                'capability lead' => 'Senior leader owning a service line',
                'diamond' => 'Top client tier (Diamond/Platinum/Gold)',
                'new applied now' => 'Brand tagline — technology + human ingenuity',
                'managed service' => 'Outsourced operations capability',
            ],
            'communication_norms' => [
                'Transformation narrative — everything is a journey',
                'Stakeholder alignment language — "bringing everyone along"',
                'Polished, structured communication — executive summaries first',
                'Framework-heavy — 2x2 matrices, maturity models',
                'Always connect to business outcomes, never just technology',
            ],
            'decision_pattern'  => 'Consensus-driven, framework-validated, sponsor-dependent',
            'meeting_culture'   => 'Deck-driven, executive summary up front, action-oriented',
            'red_flags' => [
                'Overly technical without business impact framing',
                'Skipping the "so what" — always connect to value',
                'Not knowing their client tier system (Diamond matters)',
            ],
            'power_phrases' => [
                'This accelerates your transformation journey...',
                'Our capability in this space...',
                'Aligned to your strategic priorities...',
            ],
        ],
        // Additional v1 packs: 'bofa', 'wells_fargo', 'walmart', 'us_air_force',
        // 'jpmorgan', 'deloitte', 'microsoft', 'google_cloud', 'salesforce',
        // 'us_army', 'us_navy', 'dod_civilian', 'oracle', 'sap',
        // 'ibm', 'cigna', 'unitedhealth', 'kaiser', 'anthem'
    ];

    /**
     * Format culture pack for injection into DryRunService prompt.
     */
    public static function formatForPrompt(string $companySlug): string
    {
        $pack = self::getCulturePack($companySlug);
        if (!$pack) return '';

        $sections = [];
        $sections[] = "COMPANY CULTURE CONTEXT: {$pack['company_name']}";
        $sections[] = "\nKey Vocabulary (use these terms naturally):";
        foreach ($pack['vocabulary'] as $term => $def) {
            $sections[] = "  - {$term}: {$def}";
        }
        $sections[] = "\nCommunication Norms:";
        foreach ($pack['communication_norms'] as $norm) {
            $sections[] = "  - {$norm}";
        }
        $sections[] = "\nDecision Pattern: {$pack['decision_pattern']}";
        $sections[] = "Meeting Culture: {$pack['meeting_culture']}";
        $sections[] = "\nRed Flags (things that lose credibility with this buyer):";
        foreach ($pack['red_flags'] as $flag) {
            $sections[] = "  - {$flag}";
        }
        $sections[] = "\nPower Phrases (language that resonates):";
        foreach ($pack['power_phrases'] as $phrase) {
            $sections[] = "  - \"{$phrase}\"";
        }

        return implode("\n", $sections);
    }
}

2.2 Database Schema for Custom Culture Packs

-- User-contributed / admin-curated culture packs
CREATE TABLE company_culture_packs (
    id              BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    slug            VARCHAR(50) UNIQUE NOT NULL,
    company_name    VARCHAR(200) NOT NULL,
    category        VARCHAR(50) NOT NULL,          -- hyperscaler, consulting, banking, etc.
    source          ENUM('curated', 'user', 'enrichment') DEFAULT 'curated',
    created_by      BIGINT UNSIGNED NULL,
    vocabulary      JSON NOT NULL,
    communication_norms JSON NOT NULL,
    decision_pattern VARCHAR(500) NULL,
    meeting_culture  VARCHAR(500) NULL,
    red_flags       JSON NULL,
    power_phrases   JSON NULL,
    is_public       BOOLEAN DEFAULT FALSE,         -- visible to all users?
    usage_count     INT UNSIGNED DEFAULT 0,
    created_at      TIMESTAMP,
    updated_at      TIMESTAMP,
    INDEX idx_category (category),
    INDEX idx_public (is_public)
);

-- User overlays (personal notes on top of curated packs)
CREATE TABLE company_culture_overlays (
    id              BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    user_id         BIGINT UNSIGNED NOT NULL,
    culture_pack_id BIGINT UNSIGNED NOT NULL,
    custom_vocabulary    JSON NULL,                -- additional terms
    custom_notes         TEXT NULL,                -- free-form personal notes
    custom_red_flags     JSON NULL,
    custom_power_phrases JSON NULL,
    created_at      TIMESTAMP,
    updated_at      TIMESTAMP,
    UNIQUE KEY idx_user_pack (user_id, culture_pack_id),
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
    FOREIGN KEY (culture_pack_id) REFERENCES company_culture_packs(id) ON DELETE CASCADE
);

2.3 Integration with DryRunService

The existing DryRunService::generateQuestions() method builds a prompt with persona, industry, and company type context. Culture packs slot in as an additional prompt section:

// In DryRunService::generateQuestions(), after existing context building:

// Existing
$industryContext = IndustryPersonaContext::getContext($industry);

// New — add culture pack if selected
$cultureContext = '';
if ($culturePack = $request->input('culture_pack')) {
    $cultureContext = CompanyCultureContext::formatForPrompt($culturePack);
}

// Inject into prompt after industry context:
$prompt = "...
{$industryContext}

{$cultureContext}

Generate questions this buyer persona would ask...
";

No breaking changes — culture_pack is an optional parameter. Existing dry-runs work exactly as before.

2.4 Data Source Strategy (Phased)

Phase Source Scope Effort
v1 Curated packs (hardcoded) 20 companies (hyperscalers, banks, consulting, defense) Low — PHP constants
v2 DB-backed + admin UI Admins create/edit packs, users browse Medium — CRUD + UI
v3 User overlays Users add personal notes to curated packs Medium — overlay merge logic
v4 Enrichment-derived Auto-generate culture signals from 10-K, Glassdoor, LinkedIn High — NLP pipeline

Idea 3: The "Research + Sell" Flow Question

The user asked: "If I'm researching a company, where do I input what I'm trying to sell them?"

This is the core UX question the merge solves. In the unified model:

Research Mode Input Form:
┌─────────────────────────────────────────┐
│ Target Company: [_________________________] │
│ Company URL:   [_________________________] │
│                                             │
│ What are you selling?                       │
│ ┌─────────────────────────────────────────┐ │
│ │ [Product/service description or select   │ │
│ │  from your brand voice profiles]         │ │
│ └─────────────────────────────────────────┘ │
│                                             │
│ Call Objective:                              │
│ ○ Discovery   ○ Value Prop   ○ Qualify      │
│                                             │
│ Relationship:                               │
│ ○ Partner Co-Sell   ○ Buyer   ○ New to MP   │
│                                             │
│ Output Template:                            │
│ [First Call Deck ▼]  (or Co-Sell Brief,     │
│                       Value Prop, etc.)      │
│                                             │
│ [Research & Generate]                       │
└─────────────────────────────────────────────┘

This single form answers: who am I targeting, what am I selling, why am I calling, what's our relationship, and what format do I need? Currently this is split across two separate features.


Idea 4: Partner-Buyer Matching vs Partner Co-Sell Matching

Clarification: These are two distinct motions that both live under "Research Mode":

Motion Who's Researching Who's the Target Output
Partner Co-Sell ISV partner Another ISV partner Joint GTM deck, co-sell brief
Partner-Buyer ISV partner End customer (enterprise) Value prop deck, qualification brief

The FCD wizard already handles both via its three scenarios. The merge preserves this — the "Relationship" selector in Research Mode maps directly to persona_mode in FirstCallEnrichmentSchema.


Implementation Plan: Merge FCD into GTM Studio

Decision

Merge FCD into GTM Studio as Research Mode (recommended — see analysis above).

Implementation is low-risk: the backend is already shared. The work is primarily UI reorganization and route consolidation.

Phase 1: Research Mode Tab (Core Merge)

Goal: Add "Research" as a mode/tab in the AI Presentation UI, absorbing the FCD wizard flow.

1.1 Files to Create

File Purpose
app/Extensions/AiPresentation/resources/views/modes/research.blade.php Research Mode tab content — reimplements FCD wizard steps inline
app/Livewire/Dashboard/ResearchModeWizard.php New Livewire component (replaces FirstCallDeckWizard in context of GTM Studio)

1.2 Files to Modify

File Change
app/Extensions/AiPresentation/resources/views/index-v2.blade.php Add 4-mode tab bar: Research / Create / Test / Practice
app/Extensions/AiPresentation/System/AiPresentationServiceProvider.php Add research-mode routes under /ai-presentation/research/*
app/Extensions/AiPresentation/System/Http/Controllers/AiPresentationController.php Add researchMode(), runResearchEnrichment(), generateFromResearch() methods
app/Extensions/AiPresentation/System/Services/FirstCallEnrichmentService.php No changes needed — already template-agnostic internally
app/Extensions/AiPresentation/System/Services/TemplateManagerService.php Add getEnrichmentCompatibleTemplates() — returns templates that benefit from research context

1.3 Tab Bar Implementation

{{-- index-v2.blade.php — new tab bar above existing content --}}
<div class="flex border-b border-gray-200 dark:border-gray-700 mb-6" role="tablist">
    <button
        @click="activeMode = 'research'"
        :class="activeMode === 'research'
            ? 'border-[#330582] text-[#330582] dark:text-[#9a34cd] dark:border-[#9a34cd]'
            : 'border-transparent text-gray-500'"
        class="px-6 py-3 border-b-2 font-medium text-sm transition-colors"
        role="tab"
    >
        <i class="ki-outline ki-magnifier mr-2"></i>Research
    </button>
    <button
        @click="activeMode = 'create'"
        :class="activeMode === 'create' ? '...' : '...'"
        class="px-6 py-3 border-b-2 font-medium text-sm transition-colors"
        role="tab"
    >
        <i class="ki-outline ki-document mr-2"></i>Create
    </button>
    <button
        @click="activeMode = 'test'"
        :class="activeMode === 'test' ? '...' : '...'"
        class="px-6 py-3 border-b-2 font-medium text-sm transition-colors"
        role="tab"
    >
        <i class="ki-outline ki-chart mr-2"></i>Test
    </button>
    <button
        @click="activeMode = 'practice'"
        :class="activeMode === 'practice' ? '...' : '...'"
        class="px-6 py-3 border-b-2 font-medium text-sm transition-colors"
        role="tab"
    >
        <i class="ki-outline ki-people mr-2"></i>Practice
    </button>
</div>

1.4 Research Mode — Wizard Steps (Reimplemented)

The existing FirstCallDeckWizard.php has 4 steps. Research Mode reimplements the same flow but adds template selection:

Step 1: Relationship & Objective
  - Persona mode: partner_cosell | buyer_prospect | new_to_marketplace
  - Call objective: discovery | pitch | qualify | onboard
  - Your role: alliance_manager | sales | marketing | sa | executive

Step 2: Target Company Details
  - Company name (required)
  - Company URL (optional)
  - Marketplace listing URL (optional, for partner_cosell)
  - What you're selling (textarea — or pull from brand voice)
  - Target industry (dropdown)

Step 3: Research & Enrichment
  - [Run Research] → FirstCallEnrichmentService::enrichToSchema()
  - Display enrichment dossier (company overview, market intel, news signals)
  - User can edit/annotate enrichment before proceeding

Step 4: Generate Content          ← THIS IS THE NEW PART
  - Template picker: choose ANY template (not just First Call Deck)
  - Templates flagged as "enrichment-compatible" are highlighted
  - Enrichment data passed as enrichment_data field to TemplateManagerService
  - [Generate] → same pipeline as Create Mode, but with research context injected

Key difference from current FCD: Step 4 no longer locks you into the 8-slide First Call Deck. You can take research on "Acme Corp" and generate a Co-Sell Brief, a Value Proposition deck, or a First Call Deck — your choice.

1.5 Enrichment Injection into Templates

Currently only FirstCallDeckTemplate knows how to use enrichment data. To make enrichment available to all templates:

// In PresentationTemplate.php (abstract base), add:

protected function buildEnrichmentContext(?array $enrichmentData): string
{
    if (!$enrichmentData) return '';

    return "
RESEARCH CONTEXT (from automated internet enrichment):
Company: {$enrichmentData['company_name']}
Industry: {$enrichmentData['industry'] ?? 'Not identified'}

Company Overview:
{$enrichmentData['synthesized_brief'] ?? 'No overview available'}

Key Signals:
" . collect($enrichmentData['news_signals'] ?? [])->map(fn($s) => "- {$s}")->implode("\n") . "

Market Intelligence:
" . ($enrichmentData['market_intel'] ?? 'No market data available') . "

Use this research to make the content specific and relevant to this company.
Do NOT fabricate details not present in the research.
";
}

Each template's buildPrompt() method already accepts a $context array. Enrichment data flows through as $context['enrichment_data'] — templates that want to use it call $this->buildEnrichmentContext($context['enrichment_data']). Templates that don't care simply ignore it.

Phase 2: Route Redirect & Nav Consolidation

2.1 FCD Route Redirect

// In routes/panel.php or AiPresentationServiceProvider.php

// Old route → redirect to Research Mode
Route::get('dashboard/user/first-call-deck', function () {
    return redirect()->route('dashboard.user.ai-presentation.index', ['mode' => 'research']);
})->name('panel.user.first-call-deck.index');

2.2 Nav Item Consolidation

// Migration: consolidate_fcd_nav_item.php

public function up(): void
{
    // Remove the separate "First Call Deck" menu item
    DB::table('menu_items')
        ->where('route_name', 'dashboard.user.first-call-deck')
        ->delete();

    // Update AI Presentation label to "GTM Studio"
    DB::table('menu_items')
        ->where('route_name', 'dashboard.user.ai-presentation')
        ->update([
            'title' => 'GTM Studio',
            'icon'  => 'tabler-rocket',  // or keep existing
        ]);
}

public function down(): void
{
    // Re-add FCD menu item if rolling back
    // ... inverse of up()
}

2.3 Breadcrumb & Page Title Updates

Location Before After
Page title "AI Presentation" "GTM Studio"
Breadcrumb Dashboard > AI Presentation Dashboard > GTM Studio
Hero card title "GTM Content Studio" "GTM Studio"
Hero card subtitle (current) "Research any company, generate your pitch, practice with AI buyers, then A/B test what works."

Phase 3: Practice Mode & Test Mode Tab Integration

These already exist as features — they just need to be surfaced as tabs rather than buried in the UI.

3.1 Practice Mode Tab

Currently: dry-run is accessed from within a generated presentation's detail view.

After merge: Practice Mode tab shows: - Upload a deck (existing uploadDeck() flow) - Or select from gallery (existing presentations) - Configure persona/industry/company type - Run dry-run (existing DryRunService) - View history (existing dryRunHistory())

{{-- modes/practice.blade.php --}}
<div x-show="activeMode === 'practice'" x-cloak>
    <div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
        {{-- Left: deck selection --}}
        <div class="card">
            <div class="card-header"><h3 class="card-title">Select Your Deck</h3></div>
            <div class="card-body">
                {{-- Gallery picker or upload --}}
                @include('ai-presentation::partials.deck-selector')
            </div>
        </div>

        {{-- Right: persona config --}}
        <div class="card">
            <div class="card-header"><h3 class="card-title">Configure Buyer Persona</h3></div>
            <div class="card-body">
                {{-- Persona, industry, company type, revenue tier dropdowns --}}
                {{-- Culture pack selector (Idea 2, when ready) --}}
                @include('ai-presentation::partials.dry-run-config')
            </div>
        </div>
    </div>

    {{-- Results area --}}
    <div class="card mt-6" x-show="dryRunResults">
        @include('ai-presentation::partials.dry-run-results')
    </div>
</div>

3.2 Test Mode Tab

Currently: A/B testing lives at /ai-presentation/ab-testing/* with its own views.

After merge: Test Mode tab surfaces the A/B dashboard inline: - Active tests summary - Create new test (links to existing create flow) - Test results with statistical significance

No major refactor needed — can start by embedding the existing A/B dashboard view, then iterate.

Phase 4: Cleanup & Deprecation

Task Details Risk
Deprecate FirstCallDeckWizard.php Mark as @deprecated, keep for 2 releases, then remove Low — redirect handles traffic
Deprecate FCD blade view first-call-deck/index.blade.php — show deprecation notice + redirect link Low
Update MCP tools Consolidate any FCD-specific MCP endpoints into GTM Studio namespace Low — schema unchanged
Update docs/help text Any user-facing references to "First Call Deck" as a separate product → "GTM Studio Research Mode" Low
Analytics migration Ensure FCD usage metrics map to Research Mode in analytics Medium — verify event names

Implementation Sequence

Phase 1 (Core Merge)                          ~3-4 days
├── 1a. Tab bar + mode switching (Alpine)      ½ day
├── 1b. ResearchModeWizard Livewire component  1 day
├── 1c. Research Mode blade views              1 day
├── 1d. Enrichment injection into base template ½ day
└── 1e. Template compatibility flagging         ½ day

Phase 2 (Routes & Nav)                        ~1 day
├── 2a. FCD route redirect                     ¼ day
├── 2b. Nav migration                          ¼ day
└── 2c. Title/breadcrumb updates               ½ day

Phase 3 (Tab Integration)                     ~2 days
├── 3a. Practice Mode tab                      1 day
└── 3b. Test Mode tab                          1 day

Phase 4 (Cleanup)                             ~1 day
├── 4a. Deprecation notices                    ¼ day
├── 4b. MCP consolidation                      ¼ day
└── 4c. Docs & analytics                       ½ day

Total: ~7-8 days of focused work

Risk Assessment

Risk Likelihood Impact Mitigation
Users bookmarked FCD URL High Low 301 redirect preserves access
Enrichment adds latency to non-FCD templates Medium Low Enrichment is opt-in, not default
Tab UI feels cluttered with 4 modes Low Medium Progressive disclosure — show Research + Create by default, Test + Practice as advanced
MCP consumers break Low Low Old endpoints redirect, schemas unchanged

Success Metrics

Metric Before Merge Target (30 days post)
Users confused about FCD vs AI Presentation Unmeasured (anecdotal) 0 support tickets
Enrichment usage across templates 1 template (FCD only) 3+ templates using enrichment
GTM Studio daily active users FCD + AI Pres combined Same or higher (no drop-off)
Time to first content generation ~4 min (FCD wizard) ~3 min (streamlined Research Mode)
Dry-run sessions per user per week Current baseline +20% (surfaced as tab, not buried)

Terminology Reference

Term Definition (for this document)
FCD First Call Deck — a presentation for a first conversation with a prospect or partner
GTM Studio The AI Presentation feature (/ai-presentation) — full content generation platform
Enrichment Automated internet research (Serper + marketplace scraping + Claude synthesis)
Dry-run AI buyer persona simulation — practice Q&A before a real call
A/B Testing Variant testing for marketplace listing content with statistical significance
EBC Executive Briefing Center — AWS program where partners present to enterprise decision-makers
LP Leadership Principle — AWS's 16 cultural tenets that drive decision-making
WBR/MBR Weekly/Monthly Business Review — AWS operational cadence meetings

This document captures the product clarity analysis. Implementation changes (if approved) should be tracked separately.