# The L0/L1 Standard — Definition and Ownership Criteria

Status: **normative standard** for every L0/L1 ownership decision
Date: 2026-06-11
Supersedes: the three disqualifiers of issue #2229; "what every app agrees on" as a definition
Builds on: [`l0-platform-substrate.md`](l0-platform-substrate.md) and
[`nexuscrm-platform-architecture.md`](nexuscrm-platform-architecture.md).
Retired boundary investigations are historical background only; **on ownership
questions, this document wins.**

This document is deliberately short. It is what you cite in a PR review or an
ownership dispute. Every section is normative. §6 names the only three places
where humans adjudicate. One tolerance is defined up front: vocabulary that is
*stored but never branched on* (inert residue — e.g. unused enum verbs) is
acceptable as recorded cleanup debt; anything *interpreted* is not.

## 1. Definition

> **L0 is the interpreter. L1 is everything the interpreter reads.**

L0 contains exactly three kinds of things:

1. **The metamodel** — the closed, enumerated set of structural concepts the
   platform itself is made of. This list is *decided, not derived* — see §2.
2. **Engines** — code that evaluates *any* application's registered content
   uniformly, without inspecting its vocabulary. The engine kinds are a closed
   list, exactly like the floor: metadata interpretation + persistence/query;
   permission and sharing enforcement; expression evaluation
   (formula/validation); orchestration (flow/approval); events/audit/outbox;
   pack installation and drift. Uniformity is **necessary, not sufficient**,
   for engine-hood: a uniform feature buildable on existing engines is
   registered content (T3), however generic it looks. Adding an engine kind
   follows the §2 amendment procedure.
3. **Seams** — the registration doors through which an application enters:
   metadata rows, lifecycle hooks, capability registries, dialect adapters,
   pack data.

Everything else — any fact statable only with application vocabulary, a
product's wire grammar, a version-pinned catalog, a vendor algorithm, or a
locale/currency rule — is **application content (L1)**, and may enter the
runtime only through a seam, as data.

**The picture.** L0 is a game console; applications are cartridges. The console
runs any game and knows none. The defect — every time — is a Mario circuit
soldered onto the motherboard. (Equivalently: the post office delivers any
letter; it never opens one.)

Three corollaries:

- **Store, don't interpret.** The engine may *store and transport* vocabulary —
  a row whose value happens to be `"Lead"` is fine. It may never *interpret*
  it. Interpretation includes branching on vendor naming conventions,
  field-name patterns, suffixes, or metadata shapes that only one
  application's content exhibits — not just literal noun matches. Litmus: **if
  deleting one application's pack changes the branch taken, the engine is
  interpreting.**
- **Packaging is orthogonal to ownership.** "Ships by default" is never an
  argument for L0. Batteries ship as distribution packs
  (`nexuscrm-sf-crm-pack` et al., per
  [`nexuscrm-platform-architecture.md`](nexuscrm-platform-architecture.md) §10)
  or via the `-tags crm` distribution build — never compiled into the default
  platform binary.
- **L0 membership is a permanent liability — on the contract, not the code.**
  Entering L0 means committing to never break the externally observable
  surface (§4.1). The commitment binds the contract, never the code's
  location: demotion with a contract-preserving shim is not a break (§4.5).

## 2. The scope floor — the one decision no test can make

No test can derive whether `Profile` is platform genome or Salesforce dialect.
Push any purity test to its limit and the metamodel itself — Profile, Flow,
RecordType, the `__c` suffix — becomes the largest "dialect" in the tree. That
line is **decided, not derived**:

> The platform is a **Salesforce-metamodel-compatible runtime**. The concepts
> it is made of are fixed by an explicit, enumerated, versioned allowlist —
> the **scope floor**.

Rules:

1. The floor is a **standalone enumerated document**
   ([`scope-floor.md`](scope-floor.md)) — a closed allowlist of named concepts
   with an amendment procedure.
   Analogy ("things like Profile") and open-ended categories confer zero
   entries.
2. The `constants.Table*` enumeration
   (`shared/pkg/constants/tables.go` + `z_generated_tables.go`) is the
   **namespace floor entries point into — never the membership list itself**.
   It is generated from bootstrap data, so editing a JSON must not amend the
   floor: a new `Table*` constant without a corresponding floor row is a
   violation, not an amendment.
3. **A floor entry admits a concept's *name* into the metamodel; it exempts
   nothing.** A floor concept's unit still faces T2 (it can leak a product's
   wire grammar) and T3 (it can be expressible as registered content).
   "Dashboard is on the floor" therefore never answers "does
   `dashboard_service.go` belong in the engine."
4. Any claim that a named concept is "platform genome, not a leak" **must cite
   a floor entry**. No entry, no claim.
5. Amending the floor is an architecture decision (issue + review), never a
   PR-review side effect.

**Scope floor:** the closed allowlist lives in
[`scope-floor.md`](scope-floor.md). Generated `Table*` constants, historical
boundary notes, and category phrases in
[`nexuscrm-platform-architecture.md`](nexuscrm-platform-architecture.md) confer
zero entries unless the named concept appears in that floor.

## 3. Ownership tests

**The unit under judgment** is any owned artifact: a Go package, file, or
function; a frontend module; a bootstrap/seed row; a test fixture. Two
procedural rules:

- **Split and re-enter.** Several tests split a unit (grammar from mechanism,
  primitive from feature). Each fragment is a new unit that re-enters the
  sequence from T0. "Stop at the first verdict" applies per fragment. A split
  itself confers no L0 status on any fragment.
- **Stable under decomposition.** If any decomposition of a unit yields an L1
  verdict for a part, that part is L1. Grammar cannot be laundered by
  splitting a catalog into forty one-line functions, nor by bundling grammar
  with its carrying mechanism into one package.

T0 establishes standing — it is the **only** affirmative step. T1–T2 are
disqualifiers. T3 sorts feature from primitive. T4 is the single-consumer
exception. T5 closes disputes.

### T0 — Standing test *(the only road to L0)*

**Ask:** is the unit, on its face, one of the three §1 kinds — a floor-listed
metamodel concept, an engine of a *listed kind* evaluating arbitrary
registered content without inspecting its vocabulary, or a seam?

- **No** → no L0 claim is possible. T1–T4 only determine how it leaves.
- **Yes** → standing only. It must still survive T1–T4.

For engine code, standing is **demonstrated, not asserted**: a second
registered consumer exercises it with zero engine change (in CI — see §4.3).

### T1 — Dependency test *(mechanical)*

**T1a — module closure.** Does retaining (or admitting) the unit pull any app
module (`dialect-sf-crm*`) into the platform binary's tag-free
`go list -deps` closure? Package granularity; for file/function-level units,
judge the enclosing package. For non-Go artifacts: does the default bundle,
seed set, or test tree reference an app module or app noun? (Platform test
trees use floor or toy vocabulary only.)

**T1b — vocabulary grep.** Do the unit's string literals or identifiers name
concepts absent from the §2 floor? A T1b hit is provisional — confirm it under
T2 before recording the verdict.

**Verdict:** a confirmed hit → that fragment is **L1**. Surviving T1 proves
nothing about L0-ness; continue.

### T2 — Dialect test *(one-way veto)*

Domain-neutral is not product-neutral. Zero CRM nouns is **not** an exemption.

**Ask:** does the unit encode a *product's* grammar — a wire shape
(URL/envelope/payload layout), a version-pinned catalog (the v63 function
list), a vendor algorithm (15→18 ID), a report/query DSL, a locale or currency
rule?

**Recognition rule.** A shape is a product's grammar **iff its form is pinned
by compatibility with an external product's documented surface**. A T2 "yes"
must cite the vendor document that pins the shape — or apply the **rename
test**: if NexusCRM could rename or restructure the shape in a major release
without breaking any external client's expectation, it is native syntax, not
dialect. The platform's own native wire — channels, envelopes, endpoints
NexusCRM defines and versions itself — is judged by the closed-set rider
below, not by this veto.

**Re-description does not reset T2.** If a unit's data is keyed by
verb/function/element names, that key set is the grammar under judgment,
regardless of the unit's stated purpose ("it's just a classifier/mechanism").

**Verdict:** a hit splits the unit — the grammar exits as **L1 dialect
content** immediately; the carrying mechanism is a new unit re-entering at T0.
This test never proves L0-ness.

**Closed-set rider (member-wise covariance).** For each member of a closed set
compiled into an engine — flow element kinds, action verbs, function catalogs,
enums — ask: *what event would add the next member like this one?*

- The platform language itself evolves → legitimate closed **syntax**; stays.
- An application feature or vendor release ships → **vocabulary**; it must
  move behind an open registry.

Mechanical tiebreak: a member whose semantics cite a vendor document, vendor
version, or vendor naming convention is vocabulary; a member without which the
engine cannot evaluate *any* registered content is syntax. Mixed sets are
**partitioned** — the partition is part of the verdict.

**Open registry, defined:** membership is populated at runtime through a seam
(metadata rows or pack data); adding a member requires **zero recompilation**
of the platform binary. A Go `Registry` type filled by compiled Go code is a
closed set wearing registry clothing — it does not qualify.

### T3 — Seam test *(the constructive step)*

**Ask:** can the behavior be expressed through an *existing* seam — metadata
rows, a lifecycle hook, a dialect adapter, pack data? The current seam inputs
are the platform substrate spec, the scope floor, the Salesforce v63 contract,
and any active execution ledger for the touched surface. A T3 verdict must
**name the specific seam consulted**, or state which current ledger/contract
entry was checked and found missing.

- **Yes** → it **must** be registered content. No first-party exemption: the
  platform team's own features go through the same doors.
  *Security rider:* when the behavior carries a security invariant, this
  verdict is conditional on the target seam satisfying §4.4 (fail-closed, not
  skippable-by-omission). Until such a seam exists, the verdict is **L1 with a
  recorded promotion trigger** ("migrate when fail-closed hook X lands") and
  enforcement stays engine-resident as a recorded transitional shape.
- **No** → valid only with a **failing executable demonstration** of the named
  seam attempt (a test or spike), held to the same bar as T4. The L0
  deliverable is then the **smallest missing primitive or seam at the failure
  point — never the feature itself**. ("Send email for a Lead" fails at "no
  canonical send-email verb": L0 grows the generic verb and its seam; the Lead
  binding arrives as pack metadata.)
  *Compiled-in verb clause:* a new compiled-in canonical verb is admissible
  only if (a) its name and argument contract are vendor-convention-free or
  floor-cited, (b) it dispatches through the same path as registry-supplied
  verbs, and (c) the admitting PR demonstrates a non-app-specific caller. A
  verb whose contract embeds a vendor convention (e.g. recognizing
  `ConvertedDate`-pattern fields) is vocabulary, however generic its
  implementation reads.
- **New seams need a passport:** a second consumer **already landed in-tree
  and running in CI** (running code — commitments, roadmap items, and design
  docs count for zero, consistent with T5), or a current forced leak the seam
  demonstrably retires.

### T4 — Co-location test *(the only single-consumer entry)*

**Ask:** would moving the logic outside the engine lose correctness,
atomicity, or required performance? The claim must name the **specific**
transaction boundary, lock ordering, or query plan — e.g. "row-level sharing
must be evaluated inside the query plan." "It needs a transaction" is not an
answer; the follow-up is always: *which existing in-transaction hook fails,
and what is the missing hook?*

**"Verified" means a checkable artifact**: a test that fails when the logic is
moved outside the named boundary, or a benchmark demonstrating the claimed
plan/lock behavior, landed in the admitting PR. A prose claim, however
specific, is unverified — route it through §6.

**Verdict:** specific and verified → engine-resident **L0 mechanism**.
Otherwise → **L1**.

### T5 — Default *(asymmetry)*

Still disputed after T0–T4?

- **Default L1.** Record a promotion trigger ("promote when X") instead of
  arguing.
- The burden of proof is always on whoever claims L0.
- **Incumbency counts for zero.** "It already lives in L0" and "moving is
  expensive" affect *migration scheduling and transitional shape* — never
  ownership. Roadmap promises also count for zero; only running code counts.

## 4. Obligations attached to an L0 verdict

1. **Never-break, in writing.** The admitting PR states the compatibility
   commitment for the new surface and adds a CI compatibility test. No written
   commitment, no admission. The commitment binds the externally observable
   contract — never the code's location (§4.5).
2. **Externally-paced semantics sink to data.** Content whose meaning follows
   an outside vendor's release train (v63 function semantics, report DSL,
   UI API wire) enters as registered data; only the carrying mechanism is L0.
3. **Every seam ships a real consumer.** Each L0 seam carries an in-tree,
   CI-runnable consumer from a non-CRM domain that exercises the seam's
   exported surface with **at least one input shape the first consumer cannot
   produce**. A ceremonial toy that mirrors the first consumer's wire shape
   does not qualify. A door nobody can walk through is a feature in disguise.
4. **Security seams are fail-closed.** A seam carrying security invariants
   must not be suppressible or skippable-by-omission — an undeclared
   capability that silently skips enforcement is a vulnerability, not a
   default. If the only available seam is fail-open, fix the seam *before*
   migrating enforcement into it.
5. **Demotion is not a break.** Moving a surface out of L0 requires a
   deprecation notice and a contract-preserving shim for the externally
   observable surface during the deprecation window. §4.1 can therefore never
   be cited against an L0→L1 relocation — only against breaking the contract.

## 5. Calibration anchors

Anchors are **regression tests for readings of §2–§4, not independent
authority**. Each row lists its test trace and source. If a row cannot be
reproduced from §2–§4, the row is the bug — file an amendment (§6); never cite
a row by analogy.

| Case | Verdict | Test trace | Source |
|---|---|---|---|
| Connector kernel (`connector_*`) | **L0** | T0 standing as seam-carrying mechanism, demonstrated ("second connector = zero engine change"); survives T1–T3 | #2229 KEEP-L0 finding |
| "Send email for a Lead" | verb + seam **L0**; Lead binding **L1 metadata** | T3-no at "no canonical send-email verb", compiled-in verb clause satisfied; no new Go registry | `issue-2267-flow-native-email-notifications.md` |
| `uiapi` wire shape (ObjectInfo/Layout) and currency `displayValue` formatting | **L1 dialect**, despite zero CRM nouns | T2 veto — shape pinned by the SF UI API's documented surface | `salesforce-v63-api-contract.md` |
| Flow element kinds (Decision/Loop/Wait) | closed **syntax**; stays L0 | T2 rider — defining these members cites no vendor doc; next member = platform-language event | #2229 |
| Flow `actionCall` verb set | **vocabulary** → open registry | T2 rider — next member ships with an app feature | #2229 Finding 1 |
| Formula function catalog | **partitioned** | T2 rider, member-wise: logic/control core (IF, AND, OR, NOT, …) = syntax; vendor-parity members (CASESAFEID, ADDMONTHS, IMAGE, …) = vocabulary → open registry | `backend/pkg/formula/spec/catalog.go`; #2229 Finding 5 |
| login-as | "evaluate as another principal" = **L0 primitive**; menus, audit phrasing, target policy = **L1** | T3-no names the missing primitive (shared with run-as and dashboard running-user); T4 then sites it in the permission engine on a verified query-plan claim | PR #2169 verdict |
| "Only CRM would use dashboards" | **invalid argument** | every app charts; the valid objections are T2 (SF report DSL) and T3 (expressible outside the engine) | — |

## 6. When humans decide

Exactly three places:

1. **Scope-floor amendments** (§2) — an architecture decision made by issue +
   review.
2. **T2 rider classifications** (syntax vs vocabulary) when the mechanical
   tiebreak is contested.
3. **T3-no / T4 verification disputes** — whether the named seam failure or
   transaction/query-plan necessity is real.

Procedure: file an issue labeled `layer: l0`, cite the section of this
document the dispute hangs on, and apply T5 while it is open — **the code
stays (or lands) in L1 with a recorded promotion trigger**. A dispute never
blocks shipping; it only blocks promotion into L0.
