Contact

hello@moreproof.io

howdydootoyou
← Back to Case Study

CSM Assignment Engine — Scoring Algorithm

The Constrained Greedy Heuristic

The engine uses a custom greedy assignment loop that trades academic perfection for operational reality. Accounts are pre-sorted by complexity (descending), and capacity is re-calculated dynamically after every single assignment. This prevents the classic greedy pitfall of overloading the highest-performing reps with all the difficult accounts at once.

After each assignment, the next account goes to the CSM with the most remaining capacity — but capacity is re-evaluated each round, not static.

Four-Dimension Scoring Matrix

The engine evaluates each CSM's portfolio against four weighted dimensions to produce a composite capacity score:

Volume (35%) — Proximity to Account Headcount Ceilings

volume_capacity = (max_accounts - current_accounts) / max_accounts
volume_score    = volume_capacity * 0.35

Tracks how close a CSM is to their account headcount cap. Closer to ceiling means less capacity for new accounts.

ARR (25%) — Proximity to Financial Portfolio Caps

Critical Design Decision: Capacity limits are anchored strictly to ARR, entirely ignoring TCV.

Why this matters: TCV artificially inflates the perceived workload of multi-year deals. If an engine evaluates a 3-year deal at $100K ARR as $300K TCV, it instantly eats up rep capacity. When that CSM successfully renews for a standard 1-year term, the math incorrectly registers a massive retention penalty (100K/300K). Anchoring to ARR keeps workload grounded in present-day reality.

arr_capacity = (max_arr - current_arr) / max_arr
arr_score    = arr_capacity * 0.25

Renewal Balance (25%) — Quarterly Distribution Smoothing

Ensures reps aren't buried in a single quarter. Prevents seasonal overload spikes by balancing renewal density across the year.

renewal_score = quarterly_renewal_headroom * 0.25

Portfolio Risk (15%) — Turbulence Protection

The current proportion of at-risk accounts in each CSM's book. Ensures reps with struggling portfolios aren't handed more turbulence.

health_score = (healthy_accounts / total_accounts) * 0.15

Composite Score

The final capacity score is the sum of all four dimensions:

composite_score = (
  ((max_accounts - current_accounts) / max_accounts) * 0.35 +
  ((max_arr - current_arr) / max_arr) * 0.25 +
  quarterly_renewal_headroom * 0.25 +
  (healthy_accounts / total_accounts) * 0.15
)

Higher score = more remaining capacity = better candidate for new accounts.

Key Design Patterns

🛡️ The Bouncer Pattern (White-Glove Override)

Automation handles the bulk, but human intuition handles the exceptions. If the system detects a high-value "Enterprise Alert" account (top-tier segments under ~300 total accounts), the assignment loop halts. The engine intentionally blocks direct automation for these targets.

  • Enterprise accounts get flagged for manual leadership review
  • Manual matching based on executive alignment and historical relationships
  • Standard accounts flow through the automated greedy heuristic

Follows the 80/20 rule — automation handles 80% of routine assignments, humans handle the 20% that require judgment.

🧲 The New Hire Magnet

// New hires (0-2 months tenure) get flat volume boost
new_hire_score = 85  // flat score, not calculated

// Protected by Bouncer — can't take Enterprise accounts

Ramping reps need repetitions, not complex math. The flat score turns new hires into magnets for standard accounts until they hit their targeted ramp capacity. Protected by the Bouncer pattern preventing them from taking Enterprise accounts.

Implementation Notes

Weights and caps are configurable per run via the Config module — no code changes required. All data sources normalize to a common key structure before scoring begins.

  • Totango API supplies account health, ARR, and renewal dates
  • Salesforce provides segment classification and unassigned account identification
  • Optional Glean enrichment resolves SFDC Account IDs for enrichment flows
  • All assignments go through staging → commit with full audit history

This page documents the actual scoring logic from the implementation. All team data and API tokens are sanitized — see the source repository for the full implementation.