# Salesforce-Derived L0 Boundary Ledger

Status: L0-A…L0-F roadmap closed as scoped; retained compatibility and deferred
rows below remain explicit, not silently complete
Plan: `salesforce-derived-l0-diet-plan.md`
Baseline date: 2026-06-23 · closeout: 2026-07-02 · status recon: 2026-07-13

This ledger records the Salesforce-derived mechanisms that are still present in
app-blind platform paths at the start of the L0 cleanup program. PR0 does not
move these facts. It makes them explicit, pins the migration owner, and gives
CI one place to reject unledgered backflow while later PRs remove the rows.

Rules:

- Rows with `PR1` through `PR6` began as carve or compatibility candidates.
  Their current landed, non-carve, retained-compatibility, or deferred
  disposition is authoritative; retained/deferred rows are not relabeled done.
- Count columns are machine-read by `backend/internal/boundary` tests.
- Updating a count means accepting a boundary expansion; prefer removing rows
  as migration PRs complete.

## Roadmap crosswalk (PR0–PR6 ↔ L0-A–L0-F)

This ledger's `PR0`–`PR6` numbering and the Phase-2 roadmap's `L0-A`…`L0-F`
naming are the SAME finite plan under two names — not an old plan vs. a new
one. These `PRn` labels are ledger-local; in particular, ledger `PR5` means the
L0-E component-registry candidate, not the entire Phase 2 program. Older rows
cite `PRn`; newer rows below cite the roadmap name. This crosswalk is the single
mapping:

| ledger | roadmap | scope |
|---|---|---|
| PR0 (this seal) | L0-A | boundary seal + golden baseline: **count-seals** for bounded vocabularies (service-data, tooling, formula, SObject envelope, SharingModel, lifecycle phases) + **golden tests** for pervasive behavior (routes, error envelope, access matrix, formula). CI-enforced for the covered surfaces; pervasive policy/FLS/RLS vocabulary is golden-backed, not count-sealed |
| PR1 | L0-B | Salesforce REST route / SObject wire-skin carve |
| PR2 | L0-C | Tooling DTO + SOQL/SOSL → dialect; neutral query/search IR |
| PR3 | L0-D | Policy / FLS / RLS schema-binding |
| PR4 | L0-E | records lifecycle / order-of-execution — **CLOSED non-carve (2026-07-02): the generic lifecycle engine is already neutral (capability-keyed `record_lifecycle.go`); the SF order-of-execution is a universal mechanism keyed on *persisted* trigger-type tokens → a flow-engine sub-phase, not an L0-E carve** |
| PR5 | L0-E | product component kinds / registry — **CLOSED non-carve (2026-07-02): the L0 registry is already generic (neutral `actionType`/opaque `handlerRef`); SF component kinds already live in the CRM dialect; unmatched handlerRefs are ignored, not DENY** |
| PR6 | L0-F | formula profile / evaluator / SQL-emitter hard split — **SCOPED (2026-07-02): the only real carve is the by-name `INCLUDES` SQL-emitter branches (kernel `engine.go:441` + analytics `formula_dsl_compiler.go:1333`) → a per-FunctionDefinition SQL-lowering hook + app-packs bundle; SF eval-semantics kept as an accepted L0 baseline of persisted-token contracts (deferred); the rest is generic VM / persisted language tokens** |

## L0-E / L0-F closeout (2026-07-02)

A recon-first re-scope (per the D1/D2/D5 carve-membership discipline) reclassified the last two phases; most originally-planned rows are non-carves. This section records the actual outcome so the crosswalk above is not read as still-pending work.

- **L0-E COMPLETE.** Real carves (not in the Mechanism Ledger rows above, which predate them): CreateTree SF Composite-Tree grammar → neutral `TreeNode` IR + dialect (#3386 / app-packs #299/#300 / #3389); delete 5 dead SF-shaped REST DTOs from app-blind `shared/pkg/api` (#3390); SF wire-spelling residues (allOrNone rollback message + StandardActionOutcome error codes) → dialect (#3393 / app-packs #301 / #3394). **PR4 (order-of-execution), PR5 (component kinds), and the L0-D-deferred permission-TABLE schema are all non-carve/defer** (universal + persisted + cross-repo-by-value; the permission wire shape was already carved in L0-D/D4, and its catalog relocation is a data-migration liability, not a boundary win).
- **L0-F CLOSED (2026-07-02).** "Formula = all Salesforce" is refuted: the engine is a generic expression VM plus persisted language tokens (function names, `$User/$Profile`, operators, `__r`/`__c` — baked into stored formula text, so renames are data migrations). The one real carve candidate was the `INCLUDES` SQL-emitter dispatch. **Outcome: the app-blind engine gained a neutral `FunctionDefinition.SQLLowering` capability flag (PR-A #3399) that the L1 CRM bundle sets on INCLUDES (app-packs #303); both emitters now dispatch the multipicklist-contains lowering on that flag.** The generic `MultiPicklistJSONContains*` SQL primitive was already neutral L0 and stays. The by-name `if Name=="INCLUDES"` **fallback is RETAINED as a permanent warm-upgrade compatibility shim** and its Formula Compatibility Branch Baseline rows are **NOT decremented**: formula bundles are persisted per-install in `_System_InstalledPack` and loaded at startup (`RegisterPersistedInstalledRuntimeMetadata`), so tenants that installed the CRM pack **before** the flag hold an *unflagged* persisted INCLUDES bundle; removing the fallback would break their formula recompiles on upgrade (self-delegating `formula_expr_v1` body → recurse/fail). The full-removal attempt (PR #3404) was **reverted** — Codex correctly flagged the warm-upgrade break; the earlier feasibility vet had checked the in-memory/compile-time channel but missed the persisted-installed-bundle load path. The flag is the forward-clean dispatch path and enables eventual fallback removal once every install has reapplied the pack (which normalizes the persisted bundle to carry the flag). SF eval-semantics also stay an accepted L0 baseline (deferred by architect decision). **Net L0-F = the SQLLowering flag mechanism + byte-parity goldens (PR-0a/0b); the by-name INCLUDES stays as a justified, ledgered compat shim.**

## Mechanism Ledger

| mechanism | current owner | target owner | seam | migration PR | temporary shim |
|---|---|---|---|---|---|
| Salesforce REST route and URL spelling | mixed `backend/internal/interfaces/rest`, `backend/pkg/serverruntime`, CRM distribution | CRM dialect/distribution composition | `shared/pkg/dialect` + `nexuscrm-api-host/dialecttransport` | PR1 | `/services/data` literal baseline below |
| Salesforce Tooling Flow DTO vocabulary in neutral contracts | `shared/pkg/contract` | neutral Flow IR in L0 plus Salesforce Tooling projection in CRM dialect | contract Flow admin plane | PR2 | Tooling contract baseline below |
| SOQL/SOSL query/search grammar remnants | REST query/search handlers and CRM dialect | CRM query/search dialect, L0 `queryspec`/`SearchSpec` | `shared/pkg/queryspec` | PR2 | covered by route/query golden tests |
| Policy/FLS/RLS schema names and admin projection shape | L0 permission service contracts | registered policy schema binding plus CRM projection | policy contract plane | PR3 | permission/admin golden tests |
| Salesforce records lifecycle assumptions | records save pipeline and automation hooks | **stays L0 — generic lifecycle engine already neutral** | record lifecycle contract | **PR4 — CLOSED non-carve (2026-07-02)** | lifecycle-phase freeze retained (baseline below) |
| Product component kind vocabulary | controlplane pack source/handlers | **stays L0 — registry already generic; SF kinds in CRM dialect** | pack component registry | **PR5 — CLOSED non-carve (2026-07-02)** | existing component registry tests |
| Salesforce formula spellings and native lowerings | formula engine, expression evaluator, analytics compiler | registered formula profile/evaluator/SQL emitter capabilities | formula profile + function registry | PR6 | formula compatibility baseline below |

## Service Data Literal Baseline

| path | count | migration PR | current owner | target owner |
|---|---:|---|---|---|
| `backend/distributions/crm/product.go` | 3 | PR1 | CRM distribution | CRM distribution |
| `backend/distributions/crm/runtime_route_surfaces.go` | 3 | PR1 / #4818 | CRM distribution | CRM distribution |
| `nexuscrm-audit/request_capture_middleware.go` | 2 | PR1 | app-blind audit middleware shim | CRM dialect route metadata |
| `shared/pkg/models/salesforce_flow.go` | 2 | PR2 | shared Salesforce Flow DTO comments | CRM Tooling projection |

## Tooling Contract Baseline

| path | count | migration PR | current owner | target owner |
|---|---:|---|---|---|
| `shared/pkg/contract/contract.go` | 24 | PR2 | transitional Salesforce Tooling Flow authoring compatibility surface plus Phase 1 list-view authoring seam | neutral Flow authoring IR plus Salesforce Tooling projection in CRM dialect; keep list-view payloads generic and app-pack owned |

## Formula Compatibility Branch Baseline

| path | count | migration PR | current owner | target owner |
|---|---:|---|---|---|
| `nexuscrm-analytics/formula_dsl_compiler.go` | 4 | PR6 | app-blind analytics formula SQL shim | registered formula SQL emitter |
| `nexuscrm-analytics/formula_dsl_function_helpers.go` | 1 | PR6 | app-blind analytics formula SQL helper shim | registered formula SQL emitter |
| `nexuscrm-analytics/formula_dsl_parser.go` | 1 | PR6 | app-blind analytics formula parser shim | registered Salesforce formula profile |
| `nexuscrm-analytics/formula_view_validation_projection.go` | 2 | PR6 | app-blind formula projection shim | registered Salesforce formula profile |
| `nexuscrm-kernel/pkg/expression/engine.go` | 14 | PR6 | app-blind expression evaluator shim | registered formula evaluator |
| `nexuscrm-kernel/pkg/expression/patcher.go` | 7 | PR6 | app-blind expression AST shim | registered formula profile |
| `nexuscrm-kernel/pkg/expression/walker.go` | 1 | PR6 | app-blind SQL walker shim | registered formula SQL emitter |
| `nexuscrm-kernel/pkg/formula/connector_transform_validation.go` | 22 | PR6 | app-blind formula validator shim | registered Salesforce formula profile |
| `nexuscrm-kernel/pkg/formula/engine.go` | 57 | PR6 | app-blind formula engine shim | registered Salesforce formula profile/evaluator |
| `nexuscrm-kernel/pkg/formula/field_references.go` | 2 | PR6 | app-blind formula field-reference shim | registered Salesforce formula profile |
| `nexuscrm-kernel/pkg/formula/filterformula_validation.go` | 9 | PR6 | app-blind formula validator shim | registered Salesforce formula profile |
| `nexuscrm-kernel/pkg/formula/runtime_functions.go` | 2 | PR6 | app-blind formula runtime shim | registered formula evaluator |
| `nexuscrm-kernel/pkg/formula/schema_validation.go` | 1 | PR6 | app-blind formula schema validator shim | registered Salesforce formula profile |
| `nexuscrm-kernel/pkg/formula/spec/catalog.go` | 5 | PR6 | app-blind formula catalog shim | registered formula catalog/profile |

## SObject Envelope Baseline

App-blind L0 must not grow new Salesforce SObject envelope handling (the `"attributes"` JSON key / `attributes.type`/`url` projection). Scans the **full** app-blind L0 surface (all `nexuscrm-*` core modules + `shared` + `backend/{cmd,internal,pkg}`; dialects/distributions excluded). Checked-in generated production Go remains visible to shared boundary walkers; a seal may narrow only by naming its exact owner file(s). Frozen by `TestSObjectEnvelopeShapeStaysLedgered` (marker `"attributes"`); carve in **L0-B (PR1)**.

| path | count | migration PR | current owner | target owner |
|---|---:|---|---|---|
| `nexuscrm-analytics/query_helpers.go` | 3 | L0-B (PR1) | app-blind SObject envelope compatibility shim | CRM dialect SObject envelope projection |
| `nexuscrm-automation/approval_clone.go` | 1 | L0-B (PR1) | app-blind SObject envelope compatibility shim | CRM dialect SObject envelope projection |
| `nexuscrm-automation/contract_adapter.go` | 1 | L0-B (PR1) | app-blind SObject envelope compatibility shim | CRM dialect SObject envelope projection |
| `nexuscrm-automation/flow_trigger_listener.go` | 2 | L0-B (PR1) | app-blind SObject envelope compatibility shim | CRM dialect SObject envelope projection |
| `nexuscrm-kernel/pkg/validation/schema_validator.go` | 1 | L0-B (PR1) | app-blind SObject envelope compatibility shim | CRM dialect SObject envelope projection |
| `nexuscrm-metadata/listview_authoring_contract.go` | 2 | L0-B (PR1) | app-blind SObject envelope compatibility shim | CRM dialect SObject envelope projection |
| `nexuscrm-metadata/metadata_record_types.go` | 1 | L0-B (PR1) | app-blind SObject envelope compatibility shim | CRM dialect SObject envelope projection |
| `nexuscrm-records/persistence_bulk_ops.go` | 1 | L0-B (PR1) | app-blind SObject envelope compatibility shim | CRM dialect SObject envelope projection |
| `nexuscrm-records/record_write_canonicalization.go` | 1 | L0-B (PR1) | app-blind SObject envelope compatibility shim | CRM dialect SObject envelope projection |
| `shared/pkg/models/data.go` | 4 | L0-B (PR1) | app-blind SObject envelope compatibility shim | CRM dialect SObject envelope projection |

## Lifecycle Phase Baseline

The Salesforce-derived record-write lifecycle phase set is frozen at its canonical declaration so no new phase enters app-blind L0. The generic lifecycle engine stays L0. **Closeout (2026-07-02): the SF order-of-execution is NOT an L0-E carve** — it is a universal mechanism keyed on *persisted* trigger-type tokens (relocating it would be a data migration), so it stays L0; this freeze is retained to keep new SF-specific phases out of app-blind L0. Frozen by `TestRecordWriteLifecyclePhasesStayLedgered` (marker `RecordWriteValidationPhase`).

| path | count | migration PR | current owner | target owner |
|---|---:|---|---|---|
| `shared/pkg/contract/record_write_validation.go` | 9 | L0-E: non-carve (freeze retained) | app-blind lifecycle phase declaration | stays L0 (generic lifecycle engine) |

## SharingModel Taxonomy Baseline

The Salesforce OWD sharing-model taxonomy (the actual policy *schema binding*) is frozen at its canonical enum source so no new Salesforce sharing model enters app-blind L0. Frozen by `TestSharingModelTaxonomyStaysLedgered` (marker `SharingModel`) scanning `shared/pkg/constants/enums.go`, the hand-written enum owner. Generated field/model projections remain visible to shared boundary walkers, but they are not taxonomy owners. Carve in **L0-D (PR3)**.

NOTE: the broader policy/FLS/RLS permission **vocabulary** (`FieldPermissions`, `ObjectPermissions`, `PermissionSet`, `ProfileID`) is pervasive across the permission engine and persistence (~108 app-blind files, ~1.6k refs) and is deliberately NOT count-sealed because a count-seal is the wrong tool for core permission-model types. Per the Mechanism Ledger PR3 row it is **golden-test-backed** by `nexuscrm-permissions/access_decision_golden_test.go` (object/field/row/admin access) and is carved/registered in L0-D.

| path | count | migration PR | current owner | target owner |
|---|---:|---|---|---|
| `shared/pkg/constants/enums.go` | 14 | L0-D (PR3) | app-blind OWD sharing-model taxonomy | registered policy schema binding (L1) |

## Golden Baseline Inventory

L0-A baseline rows are **live-test-backed**: a real regression test exists today
and must stay in place before behavior-moving PRs begin. A future carve may add
more cases, but it must not be the first live guard for an L0-A-required surface.

| surface | status | live test (spot-checked) | future carve |
|---|---|---|---|
| v63 route surface | live-test-backed | `backend/distributions/crm/product_test.go` (route/mount) | L0-B |
| SObject envelope | live-test-backed | dialect-sf-crm `report_wire_adapter_test.go` (+ distribution route/mount); L0 residue frozen by SObject Envelope Baseline | L0-B |
| SOQL/SOSL query/search | live-test-backed | `dialect-sf-crm-soql/parser_*_test.go` | L0-C |
| Salesforce error envelope | live-test-backed | `backend/internal/host/adapters/apihost/middleware/domain_wire_error_golden_test.go` | L0-B |
| object/field/row/admin access | live-test-backed | `nexuscrm-permissions/access_decision_golden_test.go` | L0-D |
| formula compatibility | live-test-backed | `nexuscrm-kernel/pkg/formula/*_test.go`, `nexuscrm-analytics/*_test.go` + Formula Compatibility Branch Baseline | L0-F |
