Case Study
Client Success Ops, Automated
One CSM, Six CLIs
Overview
Contract CSM, Lead-Gen Agency
Retention and expansion for an agency's client book, run as an engineering problem. The client work was the job. The tooling underneath it was what made the coverage possible.
The Engagement
Contract Client Success Manager for a paid-ads lead generation agency. The scope was the whole post-sale surface: onboarding, scheduled check-ins, day-to-day client communication, campaign performance conversations, retention, and expansion. Compensation was structured as a base plus a month-to-month tiered retention bonus plus recurring commission on closed upsells, which made speed and coverage worth real money rather than being a matter of diligence.
The Problem
The working day was scattered across four surfaces: an assigned-task panel on an internal dashboard, two separate CRM sub-accounts with their own inboxes, an overdue-accounts report, and a contact log that leadership read as the record of work. Nothing joined them. Sessions started by manually confirming a browser session and two API tokens were alive, and when one of them was not, the failure surfaced in the middle of a client conversation instead of before it. The retention bonus was calculated one calendar month at a time, so an at-risk signal missed in week one could not be recovered in week four.
The Operating Layer
I built the engagement as a command-line system rather than a browser habit. A doctor preflight verifies the browser gateway, the dashboard session, and both API tokens before any client work begins, so failure is discovered at the start of a session instead of mid-conversation. One triage command scans both CRM sub-accounts at once, with automatic retry on rate limits, gateway errors and timeouts, and loud immediate failure on auth errors, because those two classes need opposite handling. A scraper pulls the day's assigned outreach list off the dashboard, scoped to the live rows only, since every task ever created stays in the DOM as hidden history and a naive selector returns a hundred and fifty dead rows. Logging writes contacts back to the dashboard, exits non-zero when an entry fails, and refuses to run against a logged-out session rather than silently succeeding.
The Browser Migration
The dashboard has no API, so everything above depends on driving a real browser. In July a Chrome auto-update rejected a CDP command the automation library issued unconditionally on connect, and every dashboard script broke at once on a browser version nobody controlled. I collapsed all browser access behind a single seam and moved it onto a gateway that owns its own Chrome profile and absorbs upgrades itself. Six CLIs import that one module. The direct dependency went to zero, the logged-in session stopped being something each script had to re-establish, and the class of failure where a vendor upgrade takes out an entire toolchain got designed out instead of patched.
The Upsell Engine
The expansion side was a single product rolled out across an existing book, which makes it a volume motion rather than bespoke account management. I designed it as five parts: a buy-signal detector that flags inbound language about missed calls, after-hours volume and being short-staffed; an ROI calculator that turns call volume, answer rate and average ticket into a missed-revenue number before the pitch instead of during it; a pitch library covering cold, warm, demo and objection paths; an independent commission ledger keyed on opaque identifiers; and a weekly conversion funnel report reconciling pitched, demoed, closed and paid.
Diagnosis Over Reporting
The most useful output was not a dashboard. Working the accounts surfaced two operational defects behind most of the churn: a gap in the onboarding handoff affecting several accounts, and a lead-qualification defect affecting several more. Neither was a client-communication problem, which is where churn gets attributed by default. I brought the owner the root cause, the affected count, and an offer to own the fix, rather than a list of unhappy accounts. Retention arguments are won with a diagnosis attached to a proposal.
What Transfers
- 01Preflight before work. Check the session, the tokens and the gateway up front, so a broken dependency never surfaces in front of a client.
- 02Retry the transient, fail loud on the permanent. Rate limits and gateway hiccups should be absorbed; an expired token should stop everything immediately.
- 03One seam per external dependency. When a vendor upgrade breaks the browser layer, there should be a single file to fix, not six.
- 04Write results to a file, not to stdout. Long-running jobs get killed and their output truncated; the file survives.
- 05Keep your own ledger. When commission is owed on volume, an independent record is the difference between a claim and an argument.