# APAC scoring model divergence — plg-notification vs. the official production model

**Author:** Heidi · 2026-07-24
**Trigger:** flagged that `yybaroq/plg-notification`'s scoring "接错了" (got wired wrong) after a
same-day patch; re-read the repo and cross-checked it against the authoritative source.

**Authoritative source (snapshotted here):**
[`reference/APAC-Tenant-Scoring-and-Priority-20260715-snapshot.html`](reference/APAC-Tenant-Scoring-and-Priority-20260715-snapshot.html)
— pulled verbatim from
[`pingcap-support/apac_lambda_tasks/APAC-Tenant-Scoring-and-Priority.html`](https://github.com/pingcap-inc/pingcap-support/blob/main/apac_lambda_tasks/APAC-Tenant-Scoring-and-Priority.html)
on 2026-07-24 (doc itself dated "aligned with the production implementation as of 15 July 2026").

**Non-authoritative, independent re-implementation:**
[`yybaroq/plg-notification`](https://github.com/yybaroq/plg-notification) (`sql/plg_daily_digest.sql`,
`docs/scoring_model.md`) — a shadow build using Feishu Anycross + Cowork, **not** part of the landed
`apac_lambda_tasks` stack. See [`../execution/README.md`](README.md) for how the two relate.

## Why this matters, and the hard line we're drawing

Two EMEA proposals in this repo cite APAC's shadow build as prior art:
[`emea/emea-sdr-writeback-tracking-proposal-20260724.md`](../../emea/emea-sdr-writeback-tracking-proposal-20260724.md)
and
[`emea/emea-account-relationship-categorization-proposal-20260724.md`](../../emea/emea-account-relationship-categorization-proposal-20260724.md)
(renamed from "emea-reason-signal-reconciliation-proposal" to match its narrowed, business-only scope).
An earlier pass of this note argued `plg-notification`'s *delivery mechanics* (its Bitable schema, its
reason-string SQL, its reconciliation-gate implementation) were still safe to port even though its
*scoring* had drifted. That distinction doesn't hold up: **the mechanics are exactly the layer where
`plg-notification` just broke** (see the dormancy-gate bug below). We should not import any of
`plg-notification`'s engineering implementation into EMEA — not the scoring, not the gating logic, not
its specific write-back/schema design.

**What is genuinely worth learning from APAC is the business thinking, not the code**: the
account-relationship categories it introduced (net-new / open opportunity / win-back / account-no-opp /
partner-verify / active customer), the idea that an active customer re-appearing in the queue should
route differently than a fresh lead, and that a services/SI firm needs a manual check before being
counted as a direct PQL. Those are GTM judgments, portable regardless of whether the SQL underneath
them is correct. The two EMEA proposals above have been revised accordingly to drop any borrowed
implementation and keep only that business layer.

## Confirmed divergences (as of 2026-07-24)

### 1. Two entire priority rules are missing from `plg-notification`, in both the pre- and post-patch SQL

| Official rule | In `plg-notification`? |
|---|---|
| **P0**: cluster count ≥ 50 | ❌ absent — a 50+ cluster tenant is *only* P0 today via the `total≥75` fallback, which the official example (Example A: individual, 100 clusters, QPS unavailable, card on file, **Total 33**) would not even hit |
| **P1**: cluster count ≥ 10 and a known organization | ❌ absent entirely |

Official Example A is a real, documented production case: a 100-cluster individual tenant scoring
only 33 total is still final **P0**, purely on cluster count. `plg-notification` has no rule that
would score this tenant above P2 today.

### 2. Fit table doesn't match the official entity-type list

Official Fit has **8** entity types, including a value `plg-notification` doesn't model at all:

| Official entity type | Points | `plg-notification` equivalent |
|---|---|---|
| Core AI company | 30 | `company_ai_core` → 30 ✅ |
| AI-related company | 20 | `company_ai_related` → 20 ✅ |
| Non-AI company, business email | 15 | `company_non_ai` + `ent=1` → 15 ✅ |
| **AI-related institution** | **15** | **no such category** — `institution_non_ai` is the only institution bucket, flat 8 regardless of AI-relatedness |
| Non-AI institution | 8 | `institution_non_ai` → 8 ✅ |
| Non-AI company, public/free email | 5 | `company_non_ai` + `freem=1` → 5 ✅ |
| Unknown or unmatched | 3 | only reachable as the `company_non_ai` catch-all (`ELSE 3`); a truly `unknown`/unmapped `entity_ai_category` value isn't handled as its own case |
| Individual | 0 | `individual` → 0 ✅ |

### 3. The 2026-07-24 "dormancy gate" patch is not part of the official model, and appears to conflict with it

`plg-notification` added (commit `e53cc36e`, `sql: recency gates + dormancy demotion`, 2026-07-24) a
blanket rule: `QPS < 0.001 AND not ≤48h-new AND no error` → force **P2**, to fix a real false positive
(Kissflow: a dormant legacy PoC scoring P1 on stale signals). The instinct — stale static inventory
shouldn't hold a priority slot — is reasonable, but the **implementation is not in the official spec**
and, read literally, **it would override the official cluster≥50 P0 rule** for any high-cluster tenant
with zero current QPS: official Example A (100 clusters, QPS unavailable → treated as 0, no recency,
presumably no error) would be dormancy-gated to P2 under `plg-notification`'s new logic, directly
contradicting the official "Total 33, final P0" outcome for that exact profile. Whether the official
model's cluster≥50 rule *should* also have a liveness gate is a legitimate open question — but that's
a decision for whoever owns `apac_lambda_tasks`/the official scoring doc, not something a shadow build
should decide unilaterally and diverge on.

### 4. The POC and multi-cluster Urgency rules gained QPS/recency gates not in the official spec

Official: `plan = poc` → flat +15 Urency, and `clusters ≥ 3 AND no card AND known org` → flat +12,
no liveness condition on either. `plg-notification` (post-patch) requires `QPS ≥ 0.001 OR ≤48h-new` on
both. Same root issue as #3 — a plausible improvement, but an unauthorized deviation from the
documented production rules, not a fix that brings it back in line with `apac_lambda_tasks`.

## Update — 2026-07-24 (later same day): a second, larger fix round landed

APAC reported a follow-on round of fixes to `plg-notification`, synced across the live Anycross
workflow, the Cowork scheduled task, and the GitHub repo:

1. **Validated the dormancy-gate fix from §3 above in production**: after shipping the recency/liveness
   gates, their own P0 count dropped from 12 → 6 — i.e. roughly half of what the pre-patch model called
   P0 was static-signal noise (stale `poc` plans, old clusters with zero current QPS). This is
   independent confirmation that the original bug (§3/§4 above) was real and worth fixing — it just
   doesn't change the finding that the *fix itself* isn't in the official spec and may still conflict
   with the official cluster≥50 rule (see below).
2. **Added a factuality guardrail**: the enrichment layer may no longer describe a static label as a
   "reopened"/event-like narrative unless backed by real QPS or new-signup evidence; account owner is
   now always taken from the current NexusCRM value (this directly re-validates the owner-resolution
   rule already written into `emea/emea-sdr-writeback-tracking-proposal-20260724.md` — APAC hit the
   same stale-owner class of bug a second time and fixed it the same way).
3. **Fixed a real net-new misclassification bug (the "DigiPlus" case)**: an already-converted customer
   whose domain didn't directly resolve to a CRM account was being flagged as net-new. Fixed via a
   domain → Lead-Company/ConvertedAccountId bridge lookup, plus a hard rule that a domain with an Open
   Opportunity or a Converted Account is never net-new. **This is now cited as real-world evidence in
   the account-relationship-categorization proposal** (not the fix's plumbing — just the fact that the
   failure mode is real, not hypothetical).
4. Tightened churn-risk flagging (requires late-stage + recent update, not just negative ARR) and added
   display-name resolution — UX/false-positive-rate improvements, not scoring-correctness issues.

**What this update does *not* address**, as far as reported: the two missing priority rules from §1
(`cluster_count ≥ 50 → P0`, `cluster_count ≥ 10 & known org → P1`) and the Fit-category gap from §2
("AI-related institution" = 15) are not mentioned as fixed. **Treat §1 and §2 of this note as still
accurate** until independently re-verified against the current `plg-notification` SQL — this update
should not be read as "the divergence is resolved."

## Recommendation

- **Do not port any of `plg-notification`'s engineering** — not the scoring, not the reason-string SQL,
  not the Bitable/write-back mechanism, not the gating logic. It is an unofficial, currently-drifting
  shadow build, and the one time we tried to reuse "just the delivery pattern," the delivery pattern
  itself turned out to be the buggy part.
- **Do port the business ideas**: the account-relationship categorization, and the routing judgments
  that go with it (active customer → TAM path not cold outreach; win-back → elevated priority; SI/
  partner → verify before treating as a direct PQL). These are true regardless of what the underlying
  code looks like, and EMEA engineering should implement them however fits the existing
  `emea_lambda_tasks` stack — not by copying `plg-notification`'s Feishu/SQL approach.
- If APAC's own `apac_lambda_tasks` scoring has the same Kissflow-style false-positive risk (stale
  `poc` plan + old clusters, zero QPS), that's worth raising with Yujie/eng as a change to the
  **official** model and doc, going through the same review as any other scoring change — not
  something to inherit informally from the shadow build.
- The 2026-07-24 update above is a data point in favor of holding this line, not against it:
  `plg-notification` needed a *fourth* round of bug fixes on the same scoring/enrichment layer the same
  day as the original patch. That's the opposite of a settled reference implementation.
