{
  "name": "CCDocs outbound setter variance benchmark",
  "url": "https://ccdocs.com/outbound-agent-variance-benchmark/",
  "license": "https://creativecommons.org/licenses/by/4.0/",
  "attribution": "The Call Center Doctors (ccdocs.com). CC BY 4.0 -- reuse freely with attribution and a link.",
  "orderingCaveat": "This is a DISPERSION, not a correlation. The two extremes are far apart on every column, but the middle three do not order on the per-contact denominator, and dropping the single best setter -- the only one below 8 percent opt-out per contact -- makes the relationship vanish. Nothing here supports \"worse bookers burn more list\" as a rule.",
  "source": {
    "file": "apps/airoofing/files/10k_agent_scorecards.md",
    "grain": "One scorecard per agent, each stating total calls, contact calls, appointments booked and -- for seven of the eleven -- do-not-call events.",
    "corpus": "10,794 outbound roofing appointment-setting calls placed Feb-Mar 2026, transcribed and analysed. See ccdocs-roofing-call-corpus.",
    "filterReconciliation": "A second internal document publishes per-dial totals for these same five setters that run 54 calls higher in aggregate. That is exactly the non-roofing plumbing list removed from the corpus (10,848 transcribed, 54 filtered, 10,794 analysed), so the two documents are one measurement either side of one documented filter rather than two sources that disagree."
  },
  "window": {
    "corpusPeriod": "February-March 2026",
    "temporalCoverage": "2026-02-01/2026-03-31",
    "publishedDate": "2026-08-03"
  },
  "cohort": {
    "setters": 5,
    "campaigns": 2,
    "dials": 8319,
    "contacts": 4231,
    "bookings": 176,
    "doNotCall": 375,
    "rule": "The five setters who ran BOTH of the same two campaigns across the same two months. Same lists, same offer, same hours, same dialler."
  },
  "blend": {
    "bookingPerContactPct": 4.16,
    "doNotCallPerDialPct": 4.51,
    "doNotCallPerContactPct": 8.86,
    "contactRatePct": 50.86
  },
  "spreads": {
    "bookingPerContact": {
      "minPct": 2.04,
      "maxPct": 5.33,
      "ratio": 2.6
    },
    "doNotCallPerDial": {
      "minPct": 1.81,
      "maxPct": 6.4,
      "ratio": 3.5
    },
    "doNotCallPerContact": {
      "minPct": 3.47,
      "maxPct": 11.6,
      "ratio": 3.3
    },
    "contactRate": {
      "minPct": 38.1,
      "maxPct": 59.88,
      "ratio": 1.6
    }
  },
  "ordering": {
    "perDial": {
      "denominator": "do-not-call events per dial",
      "extremesOppose": true,
      "note": "The lowest booker is also the highest opt-out generator, and the highest booker the lowest. The extremes oppose on this denominator."
    },
    "perContact": {
      "denominator": "do-not-call events per contacted homeowner",
      "extremesOppose": false,
      "note": "The lowest booker is fourth of five here, and the highest opt-out rate belongs to the third-best booker. The extremes do NOT oppose on this denominator."
    },
    "headline": "This is a DISPERSION, not a correlation. The two extremes are far apart on every column, but the middle three do not order on the per-contact denominator, and dropping the single best setter -- the only one below 8 percent opt-out per contact -- makes the relationship vanish. Nothing here supports \"worse bookers burn more list\" as a rule."
  },
  "coverage": {
    "scorecards": 11,
    "withDoNotCallLine": 7,
    "doNotCallAbsent": 4,
    "inCohort": 5,
    "note": "Seven of the eleven published scorecards carry a do-not-call line: the five cohort setters and two others outside it. Four carry none at all. Those four are ABSENT from the opt-out figures on this page, never counted as zero -- their opt-out count is unknown, and an unknown rendered as a zero would invent the most flattering possible value for it."
  },
  "siblingCohort": {
    "agents": 11,
    "factId": "ccdocs-agent-booking-rate-spread",
    "note": "The eleven-agent spread is wider because it lets the campaign vary, so part of its width belongs to the campaign rather than to the person. This five-setter cohort holds the campaign fixed and measures only what is left. Neither figure corrects the other and they must not be presented as a revision."
  },
  "blindSpots": [
    "It is five people. Five is enough to show that seats differ by this much on identical work; it is nowhere near enough to establish a distribution, a median seat, or what is normal for anybody else. Do not read the ends of these spreads as best-case and worst-case for a hire.",
    "A do-not-call event is a REQUEST RECORDED BY THE SETTER, not an audited outcome. It counts what reached the disposition; it cannot count a homeowner who wanted off the list and did not say so, and it cannot distinguish a request caused by the approach from one that was coming regardless.",
    "The two campaigns are held fixed but the LIST WITHIN them was not randomised across setters. If the dialler handed systematically colder records to one seat, part of what looks like a person here is the list. Nothing in the source documents lets that be ruled out.",
    "It is one operation, one vertical and one fixed two-month window. There is no second call floor in this dataset, so nothing here establishes an industry rate for either column.",
    "It is all OUTBOUND cold dialling. Not one figure here describes how somebody who called US behaves.",
    "Bookings and opt-outs are counted; REVENUE is not. This page states that a removed record is a permanent loss of an asset the contractor paid for -- it does not price that loss, because the list cost and the lifetime value behind it are per-client figures and are not publishable here.",
    "Nothing refreshes it. It is a fixed window, deliberately: a dataset that silently re-derives itself lets a published figure change underneath a citation."
  ],
  "refusals": [
    {
      "what": "A per-setter row, on any column, under any label.",
      "why": "facts.ts states the rule under ccdocs-agent-booking-rate-spread: only the anonymous spread and the blend leave the source file. The cohort is five people on one client's Q1 rota, so relabelling the rows setter-A..setter-E does not anonymise them -- call volume alone re-identifies the order to anyone with access to that rota. The spreads and blends on this page are the whole of what is publishable, and the module has no key a row could travel under."
    },
    {
      "what": "Any agent name, on-call alias or internal agent ID.",
      "why": "The source scorecards carry real names and the aliases those people used on the phone, and the IDs resolve to real people in the dialler. They identify current or recent employees and none of them appears in this module, on the page, or in the published JSON."
    },
    {
      "what": "Any campaign code, client brand or per-campaign booking rate.",
      "why": "Each campaign maps to one contractor, so a campaign code is a client identifier and a per-campaign rate is that client's own operating number. Only the two-campaign aggregate leaves the source file, and the campaigns are referred to by count alone."
    },
    {
      "what": "The source document's ranking prose and its tier labels for individual agents.",
      "why": "Those are characterisations of identifiable employees written for an internal coaching document. They are defamation-shaped when published, and they do not become safe by being attached to an anonymised row, so none of that language travels here in any form."
    },
    {
      "what": "A significance statistic for any of these spreads.",
      "why": "The extremes do survive a two-proportion test and src/__tests__/data/agent-variance.test.ts asserts it. It is not printed because src/data/number-provenance.ts has a closed derivation op set that cannot license a z-statistic, and a number the provenance system cannot check does not belong on a page whose whole claim is that its numbers are checkable."
    },
    {
      "what": "A correlation between booking rate and opt-out rate.",
      "why": "It does not survive the choice of denominator. The extremes oppose per dial and do not oppose per contact, the middle three do not order, and dropping the best setter removes the relationship entirely. What is real is the dispersion in each column separately."
    }
  ]
}
