On this page
Three ladders state where MSO Cloud actually is. The first describes how mature an organization's marketing operation is, and is the adoption frame the MSO framework defines. The other two grade the platform itself: how trustworthy its numbers are, and how much it is allowed to act. The platform grades are dated and are not rounded up.
Each row below carries the evidence it was graded against. The evidence ladder was re-read against the code on 2026-09-18, after the platform-generalization review landed; the autonomy ladder keeps its 2026-08 reading because nothing in that review touched the action state machine, and the date on each of its rows says so.
The MSO adoption ladder#
The MSO framework describes an organization's operating maturity in five steps. This ladder is about the customer's operation, not about the platform's build status.
| Level | Operating model | Character |
|---|---|---|
| PRE-MSO | Execution systems | Disconnected, manual, fragmented |
| 1A | Adaptive execution | Closed loop begins, still within each channel |
| 1B | Unified intelligence | Connected across channels, contextualized |
| 2 | Memory systems | Compounding intelligence, the org stops restarting from zero |
| 3 | Adaptive intelligence | Adaptive reasoning support, human plus system decisioning |
At 1B the organization connects its loops across the business. At 2 it retains memory across cycles. At 3 the system supports reasoning: contextual analysis and scenario framing, with a person still making the call. The framework is explicit that Level 3 supports human judgment and does not replace it.
The platform's two ladders#
Two independent scales grade the software. The evidence ladder (L0 to L5) grades how trustworthy a produced number is. The autonomy ladder (A0 to A4) grades how much the platform is permitted to act on its own. They are independent: a high evidence grade does not grant a high autonomy grade.
flowchart LR
subgraph EV["Evidence ladder: how trustworthy the numbers are"]
direction TB
L0["L0 passed"] --> L1["L1 shipped"] --> L2["L2 shipped"] --> L3["L3 observational prototype"] --> L4["L4 prototype, substrate only"] --> L5["L5 foundation, replay half"]
end
subgraph AU["Autonomy ladder: how much the platform may act"]
direction TB
A0["A0 present"] --> A1["A1 partial, in progress"] --> A2["A2 not built"] --> A3["A3 closed"] --> A4["A4 closed"]
endEvidence ladder (L0 to L5)#
| Tier | Capability | Status (2026-09-18) | Graded against |
|---|---|---|---|
| L0 | Hard-coded reproducible playbook and decision kernel | passed | packages/metrics/src/offtake.test.ts against the frozen simulation log |
| L1 | Declarative rules with a per-predicate receipt | shipped | packages/metrics/src/playbook-rules.ts, The Decision Engine |
| L2 | Signal schema, version, and provenance, with a per-decision snapshot | shipped | signal-registry.ts, plus the fired-instance ledger in signal-events-ledger.test.ts |
| L3 | Intervention impact estimate with a valid control | observational prototype | packages/metrics/src/experiments.ts and its disclosed confounding |
| L4 | Learned policy plus off-policy evaluation, with propensity and reward per episode | prototype, substrate only | policy.ts, policy-loop.ts, lever-axis tests, policy_models.domain |
| L5 | Immutable replay, drift and calibration, real champion and challenger | foundation, replay half | decision-replay.ts plus scripts/audit/decision-replay.ts as a build gate |
What the grades mean, stated plainly:
- L0 through L2 ship. Rules, per-predicate receipts, the versioned signal registry, and per-decision snapshots run in production. L2's provenance half got stronger in September rather than higher: a fired signal INSTANCE is now persisted on its own append-only ledger with the reason it was withheld when it was withheld, which makes "why did nothing fire" a query instead of an inference. The ledger is described in From signal to decision.
- L3 is an observational prototype. Pre and post readouts run on first-party data, but they are not randomized and carry no causal identification. The readout code discloses that a pre/post comparison is confounded and is a lower bound, not a measured causal effect.
- L4 is a prototype: substrate only. A learned policy exists, and every decision now records the candidate set it chose from, the action it took, the true probability of that action, the logging policy's name and version, and a reward window declared before any outcome existed. That is the first half of the L4 requirement. The second half is missing: selection is still deterministic, so every recorded probability is certainty, and there is no effective-sample-size diagnostic, no self-normalized estimator and no confidence interval on an off-policy number. A learned policy may not be promoted on a figure with none of those. What September added was REACH, not a rung: the lever axis is no longer the five e-commerce social levers but the set an organization's activated domains declare, the policy model carries its domain inside its natural key, and the general playbook path records a lever instead of a null. Off-policy evaluation still defaults its own axis to the e-commerce list.
- L5 is a foundation, and it is now half a gate rather than none. Replay is executable: the engine re-runs a decision from the inputs the record froze, rebuilds the receipt, and compares hashes, with a three-valued verdict - identical, divergent, or unreplayable with a named reason - enforced as a build gate that passes only on zero divergences. Drift and calibration monitoring exist, and the ledger is append-only at the database. What is still missing is the other half: a data watermark proving the same window would still yield the same values, a side-by-side champion and challenger, a promotion report with an approval and a rollback path, drift that triggers an operational action, and a deletion audit for memory.
Three things that landed and deliberately do not move any grade. Episodic memory - the engine citing what happened the last time the same rule matched the same thing - and a measured track record that may reorder how playbooks are ranked are both necessary conditions for a learning loop. The third is the signal weight added in September: a hand-written correction, bounded in code and again by a database check, that may only DEMOTE a signal after repeated dismissals and never promote one. None of the three is causal evidence, and none changes what the platform is allowed to claim about an outcome.
One link is plumbed and unpopulated, and it is named here so a reader does not assume it works: the decision record carries columns for the signal instance and the signal binding version that produced it, and every writer passes null into both. "Which signal produced which decision" is therefore not yet answerable by a query.
Autonomy ladder (A0 to A4)#
Maturity is not autonomy. Reaching L4 on evidence does not grant A3 or A4 on action.
| Level | Capability | Status (2026-08) | Graded against |
|---|---|---|---|
| A0 | Explain: read governed facts and explain a receipt | present | Trợ lý dữ liệu (Chat with your data) |
| A1 | Propose: assemble evidence and propose a typed draft | partial, in progress | packages/metrics/src/offtake-loop.ts proposal path |
| A2 | Prepare: produce a bounded plan and an approval request | not built | no module; recorded as absent |
| A3 | Execute approved: dispatch an approved, version-pinned action through a durable worker | closed | the generic action table ships as a schema stub, handlers deferred |
| A4 | Bounded auto-execute: low-risk automatic execution inside policy limits | closed | closed by policy, not by absence |
- A0 is present. The chat data-assistant reads governed facts and explains a decision receipt.
- A1 is partial and is the current target. The platform can assemble evidence toward a typed draft.
- A2 is not built, and is the target after A1.
- A3 and A4 are closed. The action state machine that would dispatch or auto-execute an action is not built; the generic action table ships as a schema stub with handlers deferred. The platform recommends. A person acts.
What each ladder still needs, precisely#
Naming the missing evidence is more useful than a grade, so here it is per level.
| Level | To move up, what has to exist |
|---|---|
| L3 | A valid randomisation - geo split, switchback - or a reviewed quasi-experimental design, with assignment, eligibility, contamination, exposure, the analysis window and a pre-registered estimand all stored. Today's before-and-after readout against the same brand's own off-campaign baseline is a useful description; it does not exclude seasonality, trend, or anything else that happened at the same time |
| L4 | Randomized selection that records its own probability, plus overlap and effective-sample-size diagnostics, a self-normalized estimator alongside the doubly-structured one, and confidence intervals - all before any policy is promoted on the number |
| L5 | A pinned data watermark so replay covers the inputs as well as the kernel; a real champion and challenger running side by side; an evaluation report, an approval identity and a rollback path for every promotion; drift that triggers an operational action rather than a chart; and a deletion audit for memory |
What this means for a reader evaluating the platform#
The platform is strongest where the evidence ladder is highest: declarative rules with receipts, a provenance-carrying signal registry, honest abstention, and per-decision snapshots that ship today. It is deliberately conservative where the ladders are low: it does not claim causal measurement, it does not run a production learned policy, and it does not execute actions on its own. Those are labeled prototype, foundation, or closed here rather than described as live.
Sources#
docs/MSO-UCIP-Roadmap/mso-17-l0-l5-status.md- the internal level status this page grades againstpackages/metrics/src/decision-replay.ts,scripts/audit/decision-replay.ts- the replay half of L5packages/metrics/src/decision-episodes.ts,packages/metrics/src/policy.ts- the L4 logging contract and what is still missing from itpackages/metrics/src/decision-memory.ts,playbook-stats-rank.ts- the two additions that deliberately move no gradepackages/metrics/src/experiments.ts- the L3 readout and its disclosed confoundingpackages/schema/src/tables/signal-events.ts,signal-stats.ts- the fired-instance ledger and the weight cache over itpackages/metrics/src/offtake.ts,policy-loop.ts- the per-domain lever axis and the zero prior for an undeclared lever