Documentation Index
Fetch the complete documentation index at: https://docs.kaireonai.com/llms.txt
Use this file to discover all available pages before exploring further.
Maturity Ramp
When a new offer goes live, its propensity posterior is wide — we don’t yet know its true acceptance rate. Showing it at full ranking confidence is reckless (we might over-spend on a dud) but suppressing it entirely is also wrong (we’ll never learn). The maturity ramp is the gating decision that controls cold-start exposure as evidence accumulates. Kaireon ships two maturity ramps. The default — Bayesian Confidence-Bound Maturity Ramp (BCB-MR) — is the better one and the rest of this page covers it. A legacy linear-count ramp is kept for back-compat with tenants who tuned around a fixed interaction threshold.Why BCB-MR exists
Count-based maturity gates — “treat the model as immature until it has accumulated N responses” — are the conventional choice in next-best-action systems. The approach is intuitive but has two real failure modes:- Low-volume offers are trapped. A campaign for 100 high-value enterprise customers will never accumulate a 5,000-response gate. The model is forever immature even when its posterior is already tight — useful signal is thrown away.
- High-volume volatile offers are prematurely “done”. An offer with thousands of trials at a seasonal volatile rate still has a wide posterior. A pure count gate declares it mature even when it deserves continued exploration.
The algorithm
For each candidate offer at decision time:-
Look up the most-specific
ModelAdaptationrow (the scope hierarchy: offer → channel → direction → category → global). -
Compute the Wilson score interval for the Bernoulli proportion
p̂ = positives / (positives + negatives)at the configured confidence level (default 95%, z = 1.96). Wilson 1927 is the canonical closed-form CI; well-behaved at boundaries (no blow-up at p̂ = 0 or 1, unlike the Wald interval). -
Let
width = upper − lower. Ifwidth ≤ widthThreshold(default 0.20), the offer is mature →exposureProbability = 1.0. -
Otherwise the offer is immature. Compute a decaying cold-start floor:
At n=0 the floor is
baseFloor(default 0.50). At n=100 with default decay it’s ≈ 0.15. The decay mirrors UCB1’s√(2 ln t / n)shrinkage but applied to the floor rather than an exploration bonus. -
Return
exposureProbability = max(floor(n), wilsonLower). Themaxensures we never penalize evidence we already have — an offer with strong early positives (8/10 → Wilson lower ≈ 0.49) gets at least that lower-bound exposure even if the decay-floor shrank below it.
hash(customerId + offerId + today) ≤ exposureProbability decides whether THIS impression includes the offer.
Worked examples
The table below shows real exposure decisions at default config (widthThreshold = 0.20, baseFloor = 0.50, z = 1.96, decayHalfLife = 10).
| Positives | Negatives | Wilson lower | Wilson upper | Width | Source | Exposure |
|---|---|---|---|---|---|---|
| 0 | 0 | 0.00 | 1.00 | 1.00 | no_evidence | 0.500 |
| 1 | 9 | 0.018 | 0.404 | 0.386 | floor | 0.354 |
| 3 | 7 | 0.108 | 0.603 | 0.496 | floor | 0.354 |
| 8 | 2 | 0.490 | 0.943 | 0.452 | ci_gated | 0.490 |
| 40 | 60 | 0.309 | 0.497 | 0.188 | mature | 1.000 |
| 200 | 800 | 0.176 | 0.226 | 0.050 | mature | 1.000 |
ci_gated — exposure is the Wilson lower bound 0.49. As soon as evidence tightens the CI below 0.20 width, the offer flips to mature.
Configuration
Per-tenant settings (Settings → Models → Maturity Ramp):| Setting | Default | Effect |
|---|---|---|
maturityRampMode | "bayesian_ci" | Set to "legacy_count" to use the count-based ramp. |
maturityWidthThreshold | 0.20 | CI width below which an offer is mature. Lower = stricter. |
maturityRampColdStartFloor | 0.50 | Maximum cold-start exposure floor (the baseFloor in the formula). |
modelMaturityThreshold | 100 | Used only when maturityRampMode = "legacy_count". The number of impressions that flip an offer to mature. Set to 0 to disable the legacy ramp entirely. |
Why this design works
- Low-volume offers aren’t trapped. A campaign for 100 enterprise customers can mature once its posterior tightens, regardless of raw response count.
- High-volume volatile offers stay in exploration. An offer with thousands of trials but a still-wide CI keeps getting exploration traffic instead of being declared “done” by a count threshold.
- The threshold is principled. A 0.20 width at 95% means “the true rate is known to within ±0.10” — a tunable that business owners can reason about, with a clear posterior interpretation rather than a chosen convention.
- The maturity event is observable. Operators see a single interpretable number — “this offer’s posterior CI width is 0.18, just below the 0.20 threshold” — instead of “evidence count is 4837 of 5000”. Combined with direction-scoped adaptations, this surfaces directly in the Model Health UI.
References
- Wilson, E.B. (1927). “Probable inference, the law of succession, and statistical inference.” JASA 22:209–212. The canonical Bernoulli proportion CI.
- Auer, Cesa-Bianchi, Fischer (2002). “Finite-time Analysis of the Multiarmed Bandit Problem.” Machine Learning 47:235–256. UCB1 — origin of the √(ln t / n) shrinkage form adapted here as a decaying floor.
- Chapelle & Li (2011). “An Empirical Evaluation of Thompson Sampling.” NeurIPS. Empirical justification for Bayesian bandit-style exposure.
Code
- Library:
platform/src/lib/ml/maturity.ts - Tests:
platform/src/lib/ml/__tests__/maturity.test.ts - Call site:
platform/src/lib/pipeline-runner.ts(applyMaturityRamp)