Skip to content

Capability System Modularity Audit

Executive Summary

This document provides a comprehensive modularity audit of all 35 capabilities in the Vellocity platform. It evaluates each capability against modularity principles, identifies shared patterns, assesses dry-run/simulation potential, and provides recommendations for architectural improvements.

Key Findings: - 35 capabilities across 6 functional categories - 12 capabilities (34%) are prime candidates for DryRun integration - 8 common patterns identified for potential abstraction - 4 shared services recommended for extraction - High modularity score: 15 capabilities | Medium: 14 capabilities | Low: 6 capabilities


Part 1: Capability Inventory & Classification

1.1 Capability Categories

Category Count Capabilities
Content Generation 7 GenerateText, GenerateImage, GenerateContentSeries, GenerateMetaTags, GenerateAwsProfile, RefineContent, EnrichBrandVoice
Analysis & Intelligence 10 AnalyzeContent, CompetitorAnalysis, CompetitorBenchmark, ContentGapAnalysis, SeoContentAnalysis, SeoIntelligence, KeywordResearch, PredictPerformance, MarketplaceSeoInsight, BrandMonitoring
Co-Sell & Partnership 5 CoSellMatching, JointGTMPlanner, PartnerIntelligence, CppoProposalGenerator, DealInfluenceTracking
Marketplace Operations 4 MarketplaceAwareness, MarketplaceListingSEO, SyncMarketplaceListings, AceOpportunitySync
Knowledge & Query 3 QueryKnowledgeBase, QueryPlatformKnowledge, DiscoverSearchQuestions
External Integration 4 FetchExternalUrl, PublishToSocialMedia, AWSCleanRooms, LinkedInGraph

1.2 Capability Interface Compliance

All capabilities implement CapabilityInterface via BaseCapability:

┌─────────────────────────────────────────────────────────────────┐
│                    CapabilityInterface                          │
├─────────────────────────────────────────────────────────────────┤
│ + getName(): string                                             │
│ + getDescription(): string                                      │
│ + execute(params, context, execution): array                    │
│ + validateParameters(params): bool                              │
│ + getRequiredParameters(): array                                │
│ + getEstimatedCredits(params): int                              │
└─────────────────────────────────────────────────────────────────┘
                              │ implements
┌─────────────────────────────────────────────────────────────────┐
│                     BaseCapability                              │
├─────────────────────────────────────────────────────────────────┤
│ # getParameter(params, context, key, default): mixed            │
│ # log(message, data): void                                      │
│ # logError(message, data): void                                 │
└─────────────────────────────────────────────────────────────────┘
                              │ extends
        ┌─────────────────────┼─────────────────────┐
        │                     │                     │
   GenerateText       CompetitorAnalysis      CoSellMatching
      ...                   ...                   ...

Part 2: Modularity Assessment Matrix

2.1 Scoring Criteria

Criterion Weight Description
Interface Compliance 15% Proper use of contracts and base class
Single Responsibility 20% Does one thing well, clear boundaries
Dependency Injection 15% Services injected via constructor
Configuration Externalization 15% Hardcoded values vs configurable
Prompt Separation 10% Prompt logic separate from business logic
Response Parsing 10% Reusable parsing patterns
Testability 15% Easy to unit test in isolation

2.2 Capability Modularity Scores

Capability Score Interface SRP DI Config Prompt Parse Test DryRun Candidate
GenerateTextCapability 85 Yes
GenerateImageCapability 80 N/A No
GenerateContentSeriesCapability 78 Yes
GenerateMetaTagsCapability 82 No
GenerateAwsProfileCapability 75 No
RefineContentCapability 80 No
EnrichBrandVoiceCapability 76 No
AnalyzeContentCapability 82 No
CompetitorAnalysisCapability 88 Yes
CompetitorBenchmarkCapability 85 Yes
ContentGapAnalysisCapability 78 Yes
SeoContentAnalysisCapability 80 No
SeoContentOptimizeCapability 79 No
SeoIntelligenceCapability 77 Yes
KeywordResearchCapability 75 No
PredictPerformanceCapability 72 Yes
MarketplaceSeoInsightCapability 76 Yes
BrandMonitoringCapability 74 No
CoSellMatchingCapability 90 Yes
JointGTMPlannerCapability 86 Yes
PartnerIntelligenceCapability 82 Yes
CppoProposalGeneratorCapability 92 Yes
DealInfluenceTrackingCapability 78 Yes
MarketplaceAwarenessCapability 88 Yes
MarketplaceListingSEOCapability 80 Yes
SyncMarketplaceListingsCapability 70 N/A No
AceOpportunitySyncCapability 72 N/A No
QueryKnowledgeBaseCapability 85 N/A No
QueryPlatformKnowledgeCapability 82 N/A No
DiscoverSearchQuestionsCapability 76 No
FetchExternalUrlCapability 68 N/A No
PublishToSocialMediaCapability 72 No
AWSCleanRoomsCapability 74 N/A No
LinkedInGraphCapability 70 N/A No

Legend: ✓ = Good (90%+) | ◐ = Partial (50-89%) | ✗ = Poor (<50%) | N/A = Not Applicable


Part 3: Shared Patterns Analysis

3.1 Common Code Patterns Identified

Pattern Occurrences Capabilities Using Abstraction Potential
JSON Response Parsing 35 All AI-invoking capabilities High - Extract to trait
Prompt Building 30 All AI-invoking capabilities High - Extract to builders
BedrockService Injection 32 All AI capabilities Already abstracted
Match-based Execution 18 Multi-operation capabilities Medium - Strategy pattern
Brand Voice Context 15 Content generation capabilities High - Extract to trait
Credit Estimation 35 All capabilities Medium - Shared config
Error Logging Pattern 35 All capabilities Already in base class
Model Selection by Quality 12 Variable quality capabilities High - Use QualityConfig

3.2 JSON Response Parsing (Duplicated 35x)

Current State: Each capability implements its own parseResponse() method:

// CompetitorAnalysisCapability.php:467
protected function parseAnalysisResponse(string $response): array
{
    $response = preg_replace('/```json\s*|\s*```/', '', $response);
    $response = trim($response);
    $decoded = json_decode($response, true);
    // ...
}

// MarketplaceAwarenessCapability.php:728
protected function parseJSONResponse(string $response): array
{
    $response = preg_replace('/```json\s*/', '', $response);
    $response = preg_replace('/```\s*/', '', $response);
    // ...
}

Recommendation: Extract to shared trait:

namespace App\Traits;

trait ParsesAiResponse
{
    protected function parseJsonResponse(string $response): array
    {
        $response = preg_replace('/^```(?:json)?\s*/m', '', $response);
        $response = preg_replace('/\s*```$/m', '', $response);

        $parsed = json_decode(trim($response), true);

        if (json_last_error() !== JSON_ERROR_NONE) {
            return $this->handleParseError($response);
        }

        return $parsed;
    }

    protected function handleParseError(string $response): array
    {
        \Log::warning('Failed to parse AI response', [
            'capability' => static::class,
            'preview' => substr($response, 0, 500),
        ]);

        return ['error' => 'Parse failed', 'raw' => $response];
    }
}

3.3 Brand Voice Context Building (Duplicated 15x)

Current State: Brand voice context building is duplicated across content capabilities:

// GenerateTextCapability.php:129
if (isset($context['brand_voice'])) {
    $bv = $context['brand_voice'];
    $sections[] = "# Brand Voice Context";
    if (isset($bv['company'])) {
        $company = $bv['company'];
        $sections[] = "Company: {$company['name']}";
        // ...
    }
}

// MarketplaceAwarenessCapability.php:672
protected function getBrandContext(array $context): string
{
    if (empty($context['brand_voice'])) {
        return '';
    }
    $bv = $context['brand_voice'];
    // Same logic repeated...
}

Recommendation: Extract to shared service:

namespace App\Services\Capabilities;

class BrandContextBuilder
{
    public function build(array $context): string
    {
        if (empty($context['brand_voice'])) {
            return '';
        }

        $bv = $context['brand_voice'];
        $sections = ['# Brand Voice Context'];

        if (isset($bv['company']['name'])) {
            $sections[] = "**Company:** {$bv['company']['name']}";
        }
        // ... centralized logic

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

3.4 Quality-Based Model Selection (Duplicated 12x)

Current State: Quality-based model selection is hardcoded in multiple capabilities:

// Various capabilities
$model = match($quality) {
    'quick' => BedrockEngine::CLAUDE_3_HAIKU->value,
    'standard' => BedrockEngine::CLAUDE_3_SONNET->value,
    'deep' => BedrockEngine::CLAUDE_3_OPUS->value,
    default => BedrockEngine::CLAUDE_3_SONNET->value,
};

Recommendation: Already solved in DryRun system - extend to capabilities:

// Already exists: App\Services\DryRun\Config\QualityConfig
// Recommendation: Move to shared location and reference

namespace App\Services\Capabilities\Config;

class ModelQualityConfig
{
    public static function getModelId(string $quality): string
    {
        return match($quality) {
            'quick' => BedrockEngine::CLAUDE_3_5_HAIKU->value,
            'standard' => BedrockEngine::CLAUDE_3_5_SONNET_V2->value,
            'deep' => BedrockEngine::CLAUDE_3_OPUS->value,
            default => BedrockEngine::CLAUDE_3_5_SONNET_V2->value,
        };
    }

    public static function getSettings(string $quality): array
    {
        return match($quality) {
            'quick' => ['max_tokens' => 2000, 'temperature' => 0.7],
            'standard' => ['max_tokens' => 3000, 'temperature' => 0.5],
            'deep' => ['max_tokens' => 4000, 'temperature' => 0.3],
            default => ['max_tokens' => 3000, 'temperature' => 0.5],
        };
    }
}

Part 4: DryRun Integration Opportunities

4.1 Priority DryRun Candidates

Based on the modularity assessment, these capabilities are prime candidates for DryRun/simulation integration:

Capability DryRun Value Simulation Type Personas
CppoProposalGeneratorCapability Critical Proposal approval simulation Deal Desk, Legal, Alliance Manager, Finance
CoSellMatchingCapability Critical Partnership evaluation Partner Dev Manager, Technical Reviewer
JointGTMPlannerCapability High GTM plan viability CMO, Sales VP, Partner Manager
CompetitorAnalysisCapability High Competitive response Sales Rep, Marketing, Product
MarketplaceAwarenessCapability High Market signal validation BD, Product Marketing, Strategy
PartnerIntelligenceCapability High Partner fit assessment Alliance Manager, Partner Ops
CompetitorBenchmarkCapability Medium Benchmark validation Analyst, Product Manager
PredictPerformanceCapability Medium Forecast scenario testing Marketing Ops, Content Strategist
GenerateTextCapability Medium Content quality check Editor, Brand Manager
GenerateContentSeriesCapability Medium Campaign validation Content Lead, Social Manager
SeoIntelligenceCapability Medium SEO strategy testing SEO Specialist, Content Manager
ContentGapAnalysisCapability Low Gap validation Content Strategist

4.2 Proposed Capability Simulation Architecture

┌─────────────────────────────────────────────────────────────────┐
│                 Capability Simulation System                     │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │               SimulatableCapabilityInterface             │    │
│  ├─────────────────────────────────────────────────────────┤    │
│  │ + getSimulationContext(): array                          │    │
│  │ + getAvailablePersonas(): array                          │    │
│  │ + supportsSimulation(): bool                             │    │
│  │ + getSimulationType(): string                            │    │
│  └─────────────────────────────────────────────────────────┘    │
│                              ▲                                   │
│                              │                                   │
│  ┌───────────────────────────┼───────────────────────────┐      │
│  │                           │                           │      │
│  ▼                           ▼                           ▼      │
│  CppoProposal            CoSellMatching          GTMPlanner     │
│  Simulator               Simulator               Simulator       │
│                                                                  │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │             Shared Simulation Infrastructure             │    │
│  ├─────────────────────────────────────────────────────────┤    │
│  │ - PersonaRegistry (extended with capability personas)    │    │
│  │ - QualityConfig (shared between DryRun and Capabilities) │    │
│  │ - SimulationResult (unified result format)               │    │
│  │ - SimulationHistory (trait for history management)       │    │
│  └─────────────────────────────────────────────────────────┘    │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

4.3 CPPO Proposal Simulation Design

Use Case: Before generating a CPPO proposal, simulate approval likelihood.

namespace App\Services\Capabilities\Simulators;

class CppoProposalSimulator extends BaseSimulationService
{
    public static function getAvailablePersonas(): array
    {
        return [
            'deal_desk' => [
                'name' => 'Deal Desk Analyst',
                'icon' => 'calculator',
                'focus' => ['margin requirements', 'pricing approval', 'deal structure'],
                'description' => 'Reviews deal economics and pricing compliance',
            ],
            'legal_compliance' => [
                'name' => 'Legal & Compliance',
                'icon' => 'shield',
                'focus' => ['contract terms', 'liability', 'regulatory compliance'],
                'description' => 'Evaluates legal and compliance requirements',
            ],
            'finance_controller' => [
                'name' => 'Finance Controller',
                'icon' => 'chart-bar',
                'focus' => ['revenue recognition', 'margin analysis', 'forecast impact'],
                'description' => 'Assesses financial implications and reporting',
            ],
            'alliance_manager' => [
                'name' => 'AWS Alliance Manager',
                'icon' => 'handshake',
                'focus' => ['AWS alignment', 'marketplace compliance', 'co-sell potential'],
                'description' => 'Validates AWS partnership alignment',
            ],
        ];
    }

    public function getSimulationType(): string
    {
        return 'cppo_proposal';
    }

    protected function buildPrompt(
        SimulatableInterface $entity,
        SimulationConfig $config,
        array $persona
    ): string {
        $context = $entity->getSimulationContext();

        return <<<PROMPT
You are simulating a {$persona['name']} reviewing a CPPO proposal before submission.

## YOUR PERSONA
**Role:** {$persona['name']}
**Focus Areas:** {$this->formatArray($persona['focus'])}
**Description:** {$persona['description']}

## PROPOSAL CONTEXT
**Deal Value:** {$context['total_value']}
**Partner:** {$context['partner_name']}
**Customer:** {$context['customer_name']}
**Discount Requested:** {$context['discount_percentage']}%
**Contract Duration:** {$context['contract_months']} months

## YOUR TASK
As a {$persona['name']}, generate challenging questions and identify risks that would be raised during approval.

Return JSON:
{
  "questions": [...],
  "approval_risks": [...],
  "approval_likelihood": "high|medium|low",
  "required_clarifications": [...],
  "recommended_adjustments": [...]
}
PROMPT;
    }
}

4.4 GTM Planner Simulation Design

Use Case: Before executing a Joint GTM plan, validate strategy with stakeholders.

class JointGTMSimulator extends BaseSimulationService
{
    public static function getAvailablePersonas(): array
    {
        return [
            'cmo' => [
                'name' => 'Chief Marketing Officer',
                'icon' => 'megaphone',
                'focus' => ['brand alignment', 'market positioning', 'budget efficiency'],
                'description' => 'Evaluates marketing strategy and brand impact',
            ],
            'sales_vp' => [
                'name' => 'VP of Sales',
                'icon' => 'trending-up',
                'focus' => ['pipeline impact', 'deal acceleration', 'sales enablement'],
                'description' => 'Assesses sales impact and resource requirements',
            ],
            'product_marketing' => [
                'name' => 'Product Marketing Manager',
                'icon' => 'package',
                'focus' => ['messaging', 'competitive differentiation', 'buyer journey'],
                'description' => 'Validates product positioning and messaging',
            ],
            'partner_manager' => [
                'name' => 'Partner Manager',
                'icon' => 'users',
                'focus' => ['partner alignment', 'co-investment', 'relationship health'],
                'description' => 'Evaluates partner dynamics and collaboration',
            ],
        ];
    }

    public function getSimulationType(): string
    {
        return 'gtm_plan';
    }
}

Part 5: Modularity Weaknesses & Remediation

5.1 Critical Issues

Issue Severity Affected Capabilities Remediation
Hardcoded prompt strings High 30/35 capabilities Extract to PromptBuilder classes
Duplicated JSON parsing High 35/35 capabilities Create shared trait
No prompt versioning Medium All AI capabilities Add prompt version tracking
Tight coupling to BedrockEngine enum Medium 32/35 capabilities Abstract to model config
Missing simulation support Medium 12 key capabilities Implement SimulatableCapabilityInterface
No quality tier consistency Medium 12/35 capabilities Use shared QualityConfig

5.2 Remediation Roadmap

Phase 1: Foundation Refactoring (1-2 weeks)

  • Create ParsesAiResponse trait and apply to all capabilities
  • Create BrandContextBuilder service
  • Extract ModelQualityConfig to shared location
  • Create CapabilityPromptBuilder base class

Phase 2: Simulation Infrastructure (2-3 weeks)

  • Create SimulatableCapabilityInterface
  • Extend PersonaRegistry with capability-specific personas
  • Implement CppoProposalSimulator
  • Implement CoSellMatchingSimulator
  • Implement JointGTMSimulator

Phase 3: Integration & Testing (1-2 weeks)

  • Add simulation endpoints to capability controllers
  • Create simulation UI components (reuse DryRun modal pattern)
  • Write integration tests for simulators
  • Document simulation API

Phase 4: Extended Simulation Coverage (Ongoing)

  • Implement CompetitorAnalysisSimulator
  • Implement MarketplaceAwarenessSimulator
  • Implement ContentGenerationSimulator
  • Add simulation analytics and pattern detection

Part 6: Proposed Shared Infrastructure

6.1 New Shared Services

app/
├── Contracts/
│   └── Capabilities/
│       └── SimulatableCapabilityInterface.php    # NEW
├── Traits/
│   ├── ParsesAiResponse.php                      # NEW
│   └── BuildsBrandContext.php                    # NEW
├── Services/
│   └── Capabilities/
│       ├── Config/
│       │   ├── ModelQualityConfig.php            # NEW (or move from DryRun)
│       │   └── CapabilityPersonaRegistry.php     # NEW
│       ├── PromptBuilders/
│       │   ├── BasePromptBuilder.php             # NEW
│       │   ├── CppoPromptBuilder.php             # NEW
│       │   └── AnalysisPromptBuilder.php         # NEW
│       └── Simulators/
│           ├── BaseCapabilitySimulator.php       # NEW
│           ├── CppoProposalSimulator.php         # NEW
│           ├── CoSellMatchingSimulator.php       # NEW
│           └── JointGTMSimulator.php             # NEW

6.2 SimulatableCapabilityInterface

<?php

namespace App\Contracts\Capabilities;

use App\Contracts\DryRun\SimulationConfig;
use App\Contracts\DryRun\SimulationResult;

/**
 * Contract for capabilities that support simulation/dry-run.
 */
interface SimulatableCapabilityInterface
{
    /**
     * Check if this capability supports simulation.
     */
    public function supportsSimulation(): bool;

    /**
     * Get the simulation type identifier.
     */
    public function getSimulationType(): string;

    /**
     * Get context for simulation from current execution parameters.
     */
    public function getSimulationContext(array $parameters, array $context): array;

    /**
     * Get available personas for this capability's simulation.
     */
    public static function getAvailableSimulationPersonas(): array;

    /**
     * Run a simulation before actual execution.
     */
    public function simulate(
        array $parameters,
        array $context,
        SimulationConfig $config
    ): SimulationResult;
}

6.3 ParsesAiResponse Trait

<?php

namespace App\Traits;

use Illuminate\Support\Facades\Log;

/**
 * Shared trait for parsing AI JSON responses.
 */
trait ParsesAiResponse
{
    /**
     * Parse JSON response from AI model.
     *
     * @param string $response Raw AI response
     * @param string $context Optional context for logging
     * @return array Parsed response or error structure
     */
    protected function parseJsonResponse(string $response, string $context = ''): array
    {
        // Remove markdown code blocks
        $cleaned = preg_replace('/^```(?:json)?\s*/m', '', $response);
        $cleaned = preg_replace('/\s*```$/m', '', $cleaned);
        $cleaned = trim($cleaned);

        // Attempt direct parse
        $parsed = json_decode($cleaned, true);

        if (json_last_error() === JSON_ERROR_NONE) {
            return $parsed;
        }

        // Try to extract JSON object from response
        if (preg_match('/\{[\s\S]*\}/', $cleaned, $matches)) {
            $parsed = json_decode($matches[0], true);

            if (json_last_error() === JSON_ERROR_NONE) {
                return $parsed;
            }
        }

        // Log and return error structure
        Log::warning('Failed to parse AI JSON response', [
            'capability' => static::class,
            'context' => $context,
            'error' => json_last_error_msg(),
            'response_preview' => substr($response, 0, 500),
        ]);

        return [
            'error' => 'Failed to parse AI response',
            'raw_response' => $cleaned,
            'parse_error' => json_last_error_msg(),
        ];
    }

    /**
     * Validate parsed response has required keys.
     *
     * @param array $parsed Parsed response
     * @param array $requiredKeys Keys that must be present
     * @return bool True if all keys present
     */
    protected function validateResponseKeys(array $parsed, array $requiredKeys): bool
    {
        foreach ($requiredKeys as $key) {
            if (!array_key_exists($key, $parsed)) {
                return false;
            }
        }

        return true;
    }
}

Part 7: Value Assessment

7.1 Modularity Improvement ROI

Improvement Effort Impact Priority
Extract ParsesAiResponse trait Low (2 days) High - 35 capabilities P1
Extract BrandContextBuilder Low (1 day) Medium - 15 capabilities P1
Unify ModelQualityConfig Low (1 day) Medium - consistency P2
Create capability simulators Medium (2 weeks) High - 12 capabilities P1
Extract prompt builders Medium (1 week) Medium - maintainability P2
Add simulation UI Medium (1 week) High - user value P2

7.2 Business Value of Capability Simulation

Simulation Use Case Business Value Risk Mitigation
CPPO Proposal approval simulation Avoid wasted cycles on deals unlikely to approve ~$20K/rejected proposal
Co-sell match validation Identify partnership risks early ~$30K/failed partnership
GTM plan stakeholder simulation Reduce rework cycles ~$15K/campaign restart
Competitor response testing Better prepared sales teams Win rate improvement
Content quality simulation Fewer revision cycles Time savings

7.3 Technical Debt Reduction

Metric Current After Remediation Improvement
Lines of duplicated code ~1,200 ~200 83% reduction
Capabilities with simulation 0 12 New capability
Test coverage (capabilities) ~45% ~75% 30% improvement
Prompt management consistency Low High Standardized

Part 8: Implementation Recommendations

8.1 Immediate Actions (This Sprint)

  1. Create shared traits - Extract ParsesAiResponse trait, apply to 5 highest-traffic capabilities
  2. Unify quality config - Move QualityConfig to shared location, update capabilities to use it
  3. Document patterns - Create capability development guidelines with modularity checklist

8.2 Near-Term (Next 2 Sprints)

  1. Implement CPPO simulator - Highest business value, builds on existing DryRun infrastructure
  2. Implement Co-sell simulator - Natural extension of CoSellSimulator already in place
  3. Add simulation endpoints - REST API for triggering capability simulations

8.3 Medium-Term (Next Quarter)

  1. Full trait adoption - Apply all shared traits across 35 capabilities
  2. Prompt versioning - Track prompt versions for A/B testing and rollback
  3. Simulation analytics - Track simulation-to-outcome correlation
  4. Self-service simulation UI - Allow users to run simulations from capability UIs

Appendix A: Capability File Reference

Capability File Path Lines
GenerateTextCapability app/Extensions/ContentManager/System/Services/Capabilities/GenerateTextCapability.php 379
CppoProposalGeneratorCapability app/Extensions/ContentManager/System/Services/Capabilities/CppoProposalGeneratorCapability.php 809
CoSellMatchingCapability app/Extensions/ContentManager/System/Services/Capabilities/CoSellMatchingCapability.php 440
CompetitorAnalysisCapability app/Extensions/ContentManager/System/Services/Capabilities/CompetitorAnalysisCapability.php 483
MarketplaceAwarenessCapability app/Extensions/ContentManager/System/Services/Capabilities/MarketplaceAwarenessCapability.php 761
JointGTMPlannerCapability app/Extensions/ContentManager/System/Services/Capabilities/JointGTMPlannerCapability.php ~600
PartnerIntelligenceCapability app/Extensions/ContentManager/System/Services/Capabilities/PartnerIntelligenceCapability.php ~450

Appendix B: Existing DryRun Infrastructure Reference

Component Path Purpose
SimulatableInterface app/Contracts/DryRun/SimulatableInterface.php Entity simulation contract
SimulationConfig app/Contracts/DryRun/SimulationConfig.php Configuration value object
SimulationResult app/Contracts/DryRun/SimulationResult.php Result value object
BaseSimulationService app/Services/DryRun/BaseSimulationService.php Abstract base service
PersonaRegistry app/Services/DryRun/Config/PersonaRegistry.php Persona definitions
QualityConfig app/Services/DryRun/Config/QualityConfig.php Quality tier configuration
PresentationSimulator app/Services/DryRun/Simulators/PresentationSimulator.php Presentation dry-run
CoSellSimulator app/Services/DryRun/Simulators/CoSellSimulator.php Co-sell dry-run
ProposalSimulator app/Services/DryRun/Simulators/ProposalSimulator.php Proposal dry-run

Document generated: 2026-01-09 Author: Claude Code Audit Related: Dry-Run Feature Modularity Audit