# PQL infrastructure — target state

What the finished system is. Not who builds it, not in what order beyond the two phases below, and not
where any region stands today — that is [`current-state.md`](current-state.md).

**Direction:** unify the schema first, then move scoring into the warehouse. Collection and delivery stay
at the edges, close to the source systems and to the humans.

---

## 0. The workflow

```
 SOURCE SYSTEMS                         SHARED CORE  (one implementation, every region)
 ┌──────────────┐
 │ product      │──┐  ┌──────────────────────────────────────────────────────────────────────┐
 │ billing      │  │  │                                                                      │
 │ workload     │  ├─►│ ① COLLECT ─► ② STORE ─► ③ SCORE ─► ④ PUBLISH ─► ⑤ RETURN ─► ⑥ MEASURE│
 │ CRM          │  │  │   pull &      keep       one rule    carry        state       prove   │
 │ target lists │──┘  │   resolve     history    set         tier +       comes       an      │
 └──────────────┘     │                          config'd    state       back        effect  │
                      └────┬──────────┬───────────┬───────────┬───────────┬──────────┬───────┘
                           │          │           │           │           │          ▲
   region config ──────────┴──────────┴───────────┴───────────┴───────────┴──────────┤
   (four things only — §4)                                                            │
                                                                                      │
 ┌──────────────────────────── REGION LANES ────────────────────────────┐             │
 │  each lane consumes ④ and produces the human work:                    │            │
 │    · a ranked queue delivered to that region's channel                │            │
 │    · a human works it and records the outcome in that region's        │            │
 │      system of record                                    ─────────────┼────────────┘
 │    · that outcome re-enters the model at ⑤, and ⑥ can then show       │
 │      whether the work changed anything                                │
 └───────────────────────────────────────────────────────────────────────┘
```

The loop is what matters. A queue that goes out and never comes back is not a pipeline with a missing
feature — it is an open loop, and every rule that depends on "has anyone worked this?" is unbuildable
until it closes.

## 1. Two phases, and why in that order

**Schema before scoring.** Unifying storage is the cheaper change and the wider one: it makes every
cross-region question a single query and it stops new divergence accumulating while the rest is designed.
Moving rules into the warehouse is only safe once the inputs have one shape — otherwise the warehouse
inherits one dialect per region and the consolidation is cosmetic.

**The operating layers are absorbed, not left outside.** Where a region has built its own layer on top of
the pipeline, the capabilities it invented belong in the specification. Rules that live only in an
operating layer are unversioned, unreviewed, and invisible to scoring.

## 2. What the shared core must provide

### ① Collect

- Identity resolution that survives a login domain differing from the account record, and that **surfaces
  ambiguity** — one domain resolving to several account records is reported, never silently resolved to one.
- Every measured value arrives with an **explicit coverage status**, distinguishing *measured as zero*,
  *nothing to measure*, and *not measured*.
- Source-system limits are treated as design constraints, not as temporary annoyances: where an external
  system cannot be queried for history, the pipeline captures what it needs at the time.

### ② Store

- **One schema.** Region is a column, not a table prefix and not a database.
- **History is retained, not overwritten.** Current-state upserts are not a substitute for a time series.
- **Raw signals are kept alongside derived scores.** A stored score cannot be re-derived, re-thresholded,
  or explained after the fact without the inputs that produced it.
- **Writes cover the full population daily**, not a rotating sample. A sampled history supports
  population statistics and no per-tenant feature at all.
- **The pipeline persists its own daily snapshot of external-system state** it depends on, because
  history that is not captured at the time cannot be reconstructed later.

### ③ Score

- **One rule set, one review path.** A rule change is a diff, and the deployed behaviour is diffable
  against the specification.
- **Thresholds are configuration.** Changing a cut-off is not a code change.
- **A new arrival is reachable without accumulated score.** Scores that accumulate from usage cannot
  describe a tenant that has not used anything yet, so fit alone — who they are — admits a recent signup
  to the queue for a bounded window. This is a defined path in the model, not a downstream patch on the
  delivery layer, and it is the only place where identity outranks behaviour.
- **The shape of that path is shared; the definition of "who qualifies" is declared per region** (§4).
  The model owns the rule — when it fires, how long the window is open, how it exits, what is audited.
  A region owns only the values it is evaluated against.
- **The admission window is bounded and its exit is defined.** A fast-laned tenant has no accumulated
  score to fall back on, so when the window closes it either has behaviour to stand on or it leaves the
  queue. It never lingers on the strength of having once been new.
- The model acts on **rate of change**, not only absolute level — a tenant rising between "just signed up"
  and "above the bar" is visible without waiting to cross an absolute threshold. Without this, the fast
  lane and the threshold leave a gap that nothing observes.
- **Priority decays as well as accumulates.** A tier is a claim about *now*; without an exit path a queue
  fills with entries that were true once. The authoritative input for decay is lifecycle activity, not a
  point-sampled workload metric. Decay applies to every admission path, including the fit-based one: a
  tenant admitted on identity and never worked leaves the queue on the same terms as one that decayed out
  of it, and the record of *why* it left is the return layer's, not a note in a delivery tool.
- **Sourcing is a stored, computed property** — whether an outcome was product-led or sales-led, decided
  by whether the product signal preceded the sales record. Attribution kept as a hand-maintained list of
  names is not attribution.
- A tenant already claimed by a person is not competing for a slot in the unclaimed queue.

### ④ Publish

- The outbound channel carries **lifecycle state as well as priority**. One answers *does this deserve a
  person*, the other answers *where is this tenant stuck*; a single field cannot carry both.
- **Repeat-delivery suppression lives in the delivery system**, not in the database.
- Publishing is verifiable: a channel that is configured but inert must fail loudly, never silently
  degrade to no-op while the rest of the pipeline keeps running.

### ⑤ Return

- Follow-up state comes back into the model through **signals that fill themselves** as a by-product of
  the work — never through a field someone must remember to update.
- Both the **resulting state** and the **evidence that the record was touched** are captured. The
  destination state alone misclassifies real triage as inaction: a considered decision to park something
  looks identical to nobody having looked.
- Automated and human writes are distinguishable, so a bulk system update is never read as human attention.
- **Routing precedence:** where an account already has an owner, follow-up belongs to that owner; the
  regional assignment table applies only where it does not.
- Recording an outcome requires no database credential in a human's hands.

### ⑥ Measure

- The effect of an intervention on a tenant is **provable** — which is a property of stored history, not
  of reporting. This is the layer that answers "did any of this work", and it is the reason the store
  guarantees are not negotiable.
- Outcomes reached through the delivery channel are joined back to the tenant that triggered them.

## 3. Invariants

- Never build a mechanism on a field a human must remember to fill.
- Not-measured and measured-as-zero are opposite facts and never collapse into one value.
- Absence of a logged action is not evidence that no action was taken.
- Internal enrichment or pipeline failures never contribute to a score and never gate a tier.
- Time-based rules count observation days, not calendar days.
- Regional tier counts are not comparable and are never summed without stating each definition.
- A point sample is not an average, and missing coverage is never rendered as zero usage.
- Deployed code is the authority; a specification that cannot be diffed against it is decoration.
- Exclusions are auditable and their release is deliberate — a suppressed record is reported, not silent.

## 4. The regional interface

A region sets four things. Everything else is shared.

| Region sets | Because |
|---|---|
| **Thresholds and tier cut-offs** | the same absolute cut-off means different things at different population sizes |
| **Fit vocabulary, and the ICP admission definition** | a segment that is meaningful in one market can be empty in another; see below |
| **Routing table** | sales organisation and coverage differ; the precedence rule above does not |
| **Delivery channel and language** | where the queue is delivered, and to whom, in what language |

Anything else that differs between regions is divergence, not adaptation.

### The regional declaration

A region does not write a rule. It fills in a declaration with a fixed shape, and the shared rules
evaluate against it. This is what makes "our ICP is different" expressible without a second
implementation.

| A region declares | Example of the kind of value | Used by |
|---|---|---|
| Which fit categories qualify | a subset of the shared fit taxonomy | the fit-based admission path, and fit scoring |
| The firmographic bar | a size or maturity threshold, in the units the shared enrichment provides | admission, and the below-bar branch |
| Hard exclusions | segments never admitted regardless of behaviour | admission and scoring, applied before anything else |
| Admission window length | how long identity alone keeps a new arrival in the queue | the fast lane's opening and its exit |
| The unknown branch | what happens when enrichment cannot decide — admit, hold, or count without listing | admission, so "we don't know" is a stated choice rather than an accident |
| Tier cut-offs and the routing table | as above | scoring and delivery |

**Three constraints keep this from becoming divergence again:**

- **Values, not logic.** A region supplies inputs to shared rules. It never supplies a predicate, a
  branch, or an exception. If a region needs something the declaration cannot express, that is a change
  to the declaration's shape — reviewed once, available to every region — not a local rule.
- **The declaration is versioned and readable**, so "why did this tenant surface here and not there" is
  answerable by diffing two declarations rather than by reading two implementations.
- **Its effect is reported back.** How many arrivals a region's definition admitted, held and filtered is
  visible to that region. A bar set too high produces silence, and silence is indistinguishable from a
  quiet market unless the filtering is counted.

## 5. Open questions for the discussion

1. Does the physical separation between regional databases reflect a residency or latency requirement, or
   is it historical? The answer decides whether "one database" is available, or whether the target is one
   *schema* across separate stores with the warehouse as the single join point.
2. Does each region keep its own system of record for follow-up state, or is there one? Both are workable;
   they imply different return-layer designs.
3. Who owns a rule once it is shared — one owner for the pipeline, or one per region with a shared
   specification?
4. Where scoring moves into the warehouse, warehouse latency becomes the pipeline's floor. Which paths, if
   any, need sub-hour freshness and must therefore stay in the collection layer?
5. Should regional operating layers converge into the pipeline, or continue as fast-moving delivery layers
   whose rules are merely made visible and versioned?

## 6. What this implies has to change

Stated as changes, not as assignments.

The categories below are the same four used in [`current-state.md`](current-state.md) §6 — *data source*,
*infrastructure*, *logic*, *configuration* — so a gap there maps to a change here without translation.

**Infrastructure — a change to the pipeline itself**

- One schema with region as a column; region-only concepts promoted to columns or defined once for
  everyone, and stubs that were never wired removed.
- Snapshot storage gains raw signal columns and a full-population daily write.
- A producer for product-event data in every region, not only where one happens to exist.
- Follow-up state written back from the region's system of record by the job that already reads it.
- Attribution and coverage status stored as fields, not derived by hand at reporting time.
- Scoring expressed as reviewable, diffable rules with configuration-level thresholds.

**Data source — a source that does not exist, or has not been granted**

- Lifecycle activity, for the decay rule to rest on a measurement rather than a proxy.
- Batch access to the CRM record set, for cohort-level measurement rather than per-record lookups.

**Logic — rule corrections that need no new capability**

- Removing rules that cannot fire in the region where they are deployed.
- Removing rules that score internal failures.
- Aligning rules that exist in one region only, where the divergence has no stated reason.

**Configuration — settings, no code**

- Verifying that each publish channel is actually live rather than silently disabled.
- Building the publish path where a fork dropped it.
- Repeat-delivery suppression in the delivery system.
