# pql-infrastructure

**PQL (Product-Qualified Lead) infrastructure for TiDB Cloud.** *(Renamed from `pql-modeling`
2026-08-27 — old links redirect. The scope outgrew "modeling": this covers collection, storage,
scoring, publishing, follow-up return and measurement, of which the model is one layer.)*

This is the signal / scoring layer of the
**PLG motion** that serves **life-cycle-growth** (全生命周期增长).

**LOCKED 2026-09-04:** every artifact from this PQL infra is labeled **PLG**, never SLG.
See [`AGENTS.md`](AGENTS.md).

```
signup → activated → aha → PQL → paid → expansion → churn-risk
                       └──────── this repo scores here ────────┘
```

We surface, from product behavior, *which self-serve tenants are worth a human's time right now* and
hand them to regional follow-up — without burning sales time on non-ICP usage.

## How this repo is organized

Each region is **its own sub-folder with its own data sources, thresholds, and ops**. The shared
contract lives in `universal/`. Regions do **not** share a database; they share a *model contract*.

| Path | What it is | Status |
|------|------------|--------|
| `universal/` | Region-agnostic model: Fit × Signal framework, aha-moment ladder, the tenant-grain field contract every region must emit, the QPS time-series signal contract, and the delivery architecture. | contract |
| `emea/` | **V0 Live.** Live in production. v0 additive score + v1 three-queue upgrade proposal. Engineering repo — [emea_lambda_tasks](https://github.com/pingcap-inc/pingcap-support/tree/main/emea_lambda_tasks). | live (v0) |
| `apac/` | **Plan vs. build diverged.** v1 planning docs here (Fit × Signal, India + APAC-Others). Engineering already built + deployed a different scoring pipeline — [apac_lambda_tasks](https://github.com/pingcap-inc/pingcap-support/tree/main/apac_lambda_tasks), comparison in [`apac/execution/README.md`](apac/execution/README.md). | building / partly live |
| `latam/` | **Burn-in.** Mexico + Brazil. Runs the EMEA + APAC model unchanged into `latam_active_tenants` (DB `latam_regional_support`); thresholds not yet tuned for the region. Engineering repo — [latam_lambda_tasks](https://github.com/pingcap-inc/pingcap-support/tree/main/latam_lambda_tasks). | burn-in |

## The model in one paragraph

A tenant is scored on two axes. **Fit** = "should a human spend time on this account?" (corporate /
AI domain vs. free-email/individual). **Signal** = "is the product behavior meaningful?" (data
import, sustained workload, card on file, spending-limit raises — *not* just signing up or spinning
a cluster). The two axes cross into **P0 (hand off now) / P1 (high intent, nurture/enrich) / P2
(monitor)**, with hard guardrails: high-usage non-ICP is suppressed, and a real migration import
always outranks a premium click. Full definition: [`universal/pql-framework.md`](universal/pql-framework.md).

## Aha moments (what actually counts as progress)

Binding a card is **not** the only — or the strongest — signal. The ladder, and which signals are
wired vs. still blocked on a data source, is in [`universal/aha-moments.md`](universal/aha-moments.md).
Strongest → weakest: **data import (migration) > sustained QPS / first DDL > card / spending-limit
raise > multi-cluster > first query > cluster created**.

Sustained QPS is currently **not measurable** — there is no daily tenant-grain QPS table. The open
data request to infra (definition, schema, retention, acceptance check) is
[`universal/REQUEST_tenant_daily_qps_view.md`](universal/REQUEST_tenant_daily_qps_view.md)
([#18](https://github.com/pingcap-inc/pql-infrastructure/issues/18)).

**Interim design while four upstream signals are unavailable** (active-user detail frozen
2026-07-07, import, first DDL, daily QPS — all P0 in `GROWTH_DATA_BREAKS_AND_RESTORATION.md`,
2026-08-20): lean harder on the QPS we do still collect and extract time-series features from it.
Contract: [`universal/qps-timeseries-signal-contract.md`](universal/qps-timeseries-signal-contract.md).
Its Tier A rules need no new data; its Tier B features are blocked on
[`latam/REQUEST_snapshot_signal_history.md`](latam/REQUEST_snapshot_signal_history.md), which asks
engineering to persist raw signals in `*_tenant_score_snapshots` (today they store only the derived
score, so QPS history has never been retained). Both landed here 2026-08-26; **the snapshot request
has not yet been filed with `pingcap-support`** — check the engineering repo before repeating that
status.

## This repo is intent; `pingcap-support` is truth

Region folders here describe what was *planned and agreed*. What actually *runs* lives in
[`pingcap-inc/pingcap-support`](https://github.com/pingcap-inc/pingcap-support) —
`emea_lambda_tasks` / `apac_lambda_tasks` / `latam_lambda_tasks`. Status lines here carry a
`checked <date>` and go stale within weeks.

**Before repeating any claim from this repo that something is not built, not live, or blocked, check
the engineering repo.** This has already burned us: `apac/execution/README.md` said the HubSpot
write-back had no code, and it had shipped to production the same day that line was written — the
claim then sat here uncorrected for a month.

## Credentials — never in this repo

This repo is private but **~195 `pingcap-inc` members inherit read access**, so anything committed
here is effectively shared with all of them. No database password, DSN, or service-account key goes
in, for any region — EMEA and APAC set this rule and LATAM follows it. Scripts read credentials from
the environment (`REGIONAL_SUPPORT_DSN`, `TIDB_PASSWORD`, `GOOGLE_APPLICATION_CREDENTIALS`); host,
port, user, database, and table names are fine to document. Same rule for query-result snapshots and
CSV exports — they carry tenant PII and are gitignored.

## For engineers picking this up

1. Read [`universal/pql-framework.md`](universal/pql-framework.md) and [`universal/data-contract.md`](universal/data-contract.md) — the model and the fields you must emit.
2. Read [`emea/EMEA-Signal-Model-v0.sql`](emea/EMEA-Signal-Model-v0.sql) and `emea/emea-pql-model-upgrade-proposal-20260624/` — the proven implementation you are forking.
3. For APAC, start at [`apac/README.md`](apac/README.md) → [`apac/apac-pql-v1.sql`](apac/apac-pql-v1.sql).
4. Delivery is three layers, not just SQL — see [`universal/delivery-architecture.md`](universal/delivery-architecture.md).
