# ADR: Bounded Runtime Selected-Root Record Read

> **Lifecycle scope (2026-09-07):** Catalog-bound wire receipts below describe
> the existing record protocol, not an online configuration publication owner.
> [The configuration boundary](configuration-and-execution-lifecycle.md) governs
> editable facts. Keep existing wire/security behavior until a complete consumer
> migration; do not use MinCatalogRevision as the save token for UI configuration.

> **Status:** **APPROVED** by P1c-D; **P2 IDL/generation and the P2-P4/P6
> implementation gates are complete**. The stdlib-only semantic module remains
> separate from generated protobuf/gRPC: NexusCRM currently consumes
> `nexuscrm-contract v0.1.5` plus `wire-go v0.1.1`. The real Runtime adapter,
> dormant sfcrm client, and CI-only issue-tracker conformance fixture are merged.
> Values classified `DEFERRED` remain owned by their named cutover gates. C0
> found no behaviorally equivalent production CRM route, so this approval owns
> no production traffic, App installation, or first-cutover claim.
>
> **Capability:** `runtime.records.read-selected-root.v1`
>
> **Evidence revisions:** NexusCRM envelope owner inventory
> `ad742ee0e502bf43e9084960e30c207b026a4bce`, route-budget ownership
> `1968d182806e16633fd7d63041bc91a0ea508b3c`, and final M2d-C execution
> evidence `34e82a93feef1f248fb6da3b0077c7751f64dcc6`; nexuscrm-app-packs production
> tree `bb138effbe9c2857db432224892c232e14bddf80`; merged issue-tracker fixture
> `ec2ed3b2f0501d749f7a2b2eac1a86bbeba506b8`.

## 1. Decision and scope

The first neutral Runtime data operation is a bounded point read of one record
with an explicit selection of root fields. Runtime resolves the object and
field metadata from its one bound `RuntimeMetadataView`, revalidates trusted
identity and App-installation authority, and enforces object CRUD, RLS, and FLS
before returning one typed projection.

The operation is semantically named `ReadSelectedRecord`; the capability name,
not any Go or protobuf method spelling, is normative.

The operation includes:

- one object identifier and one record identifier;
- a non-empty, bounded set of selected root-field identifiers;
- typed present values, explicit null, and omitted/absent fields;
- stable success, authorization, missing, cancellation, compatibility, stale
  state, capacity, availability, and internal-failure outcomes;
- immutable metadata/security binding and version receipts.

The operation excludes lookup labels, parent or child records, relationship
paths, child collections, graphs, formulas requiring a second L1 call, public
CRM envelopes, and issue-tracker vocabulary. A reference field may return only
its root reference identifier. Partial results are forbidden.

This ADR specifies semantics, not IDL. P2 subsequently chose the wire field
numbers and generated package names in the separately versioned `wire-go`
module while preserving the approved decisions and executable gates in Sections
9.12 and 11. Future wire evolution must continue to preserve that separation.

## 2. Current consumers and the common operation

### 2.1 Current CRM point-read path; no exact selected-root route

At nexuscrm-app-packs `bb138eff`, the production route is registered as
`GET /sobjects/:sobject/:id` in
`dialects/dialect-sf-crm/partition.go:1128-1133`. Its handler performs:

1. object metadata describe (`records.go:52-57`);
2. `contract.Records.Retrieve` (`records.go:59-65`);
3. CRM projection plus a separate policy read (`records.go:67-75`);
4. lookup hydration and relationship nesting (`records.go:76-77`);
5. CRM-only decoration, attributes, and activity tracking
   (`records.go:79-94`).

Lookup hydration describes the root again, then for every distinct lookup
target type describes and batch-retrieves the target, then describes the target
again for every readable reference (`records.go:882-950`). If each current
in-process call became a network call, the derived count would be
`4 + 2T + R`, where `T` is distinct target types and `R` is readable reference
values. That violates the target architecture's shape-independent RPC budget.

The current root read itself reaches NexusCRM's public neutral adapter:

```text
sfcrm GET handler
-> contract.Records.Retrieve
-> records.ContractService.Retrieve
-> records.PersistenceService.Retrieve
-> metadata/CRUD -> record repository -> RLS -> FLS
```

Evidence in NexusCRM `d922eec39`:

- `nexuscrm-records/contract_adapter.go:29-31` delegates directly to
  `PersistenceService.Retrieve`;
- `nexuscrm-records/persistence_bulk_ops.go:743-791` performs object Read,
  one root repository read, missing/RLS masking, and FLS filtering;
- `nexuscrm-records/persistence_bulk_ops.go:761-769` deliberately gives missing
  and RLS denial the same not-found result;
- `nexuscrm-records/persistence_bulk_ops.go:772-784` omits unreadable fields.

The selected-root portion is a reusable internal prefix, not an independently
movable product operation. The C0 current-tree consumer audit
([`c0-first-real-crm-consumer.md`](../refactor/serviceification/c0-first-real-crm-consumer.md))
confirmed that no production CRM route, UI operation, or internal product
consumer is behaviorally equivalent to this v1 capability. The sfcrm
`RuntimeSelectedRootClient` remains explicitly dormant and owns no route.

The complete SObject route still owns compound synthesis, lookup hydration,
relationship nesting, decoration, attributes, and activity. It remains on its
current owner until a separately justified coarse record-view contract exists.
C0 instead selects UI API record-access as the first production ownership
slice; that operation returns access decisions rather than selected field
values and requires a different contract. This finding changes no selected-root
semantic or wire behavior.
P4's real cross-process proof for the dormant client remains valid conformance
evidence; it did not register a route owner. CRM-specific lookup hydration is
never silently converted into additional Runtime RPCs.

### 2.2 CI-only issue-tracker path

The merged app-packs fixture at `ec2ed3b2` defines exactly one public-neutral
dependency, a `PointReader` satisfied by `contract.Records.Retrieve`
(`tests/conformance/issue-tracker/point_read.go:64-68`). It normalizes one
record identifier and an explicit root selection, calls the reader once, and
projects only present selected values (`point_read.go:113-168`).

NexusCRM P1b executes a reviewed snapshot through the real adapter:

- `nexuscrm-records/issue_tracker_conformance_test.go:114-142` constructs the
  consumer and invokes it;
- `nexuscrm-records/issue_tracker_conformance_test.go:146-168` wires the real
  `ContractService -> PersistenceService` adapter with public metadata and
  permission services;
- `scripts/ci/test-issue-tracker-runtime-conformance.sh:41-69` runs that test
  and checks the fixture's test dependency closure;
- `scripts/ci/check-sealed-conformance-fixture-boundary.sh` verifies the sealed
  app-packs fixture is byte-identical to the reviewed snapshot, rejects every
  retired release-shaped path, and rejects the fixture from records, server,
  Runtime, CRM distribution, and image dependency closures.

The fixture is a CI conformance consumer only. P1x physically removed its old
pack, dialect, frontend, distribution, install, and deployment shapes. It owns
no product route, AppService, image, manifest, AppInstallation, SLO, or
deployment claim.

### 2.3 Implemented conformance operation and RPC budget

The dormant sfcrm adapter and CI-only issue-tracker fixture implement:

```text
authenticated execution context
+ object identifier
+ record identifier
+ selected root fields
-> one complete authorized typed root projection OR one stable failure
```

For a valid delegation, one L1 record-read request makes exactly **one Runtime
data RPC**. Identity exchange is a separate authenticated delegation lifecycle,
not a metadata/policy call performed per selected field. The Runtime RPC budget
does not count Runtime-internal metadata, permission, cache, or database queries;
those remain implementation details inside the L0 logical service and require
their own database-query performance accounting.

The L1 must not call Runtime separately for schema, object permission, FLS,
RLS, lookup targets, or each field. App presentation may use its authorized
local `AppMetadataView` projection, but that projection is not authorization;
Runtime remains the enforcement authority.

## 3. Semantic request and result

### 3.1 Request

The semantic request contains only:

```text
ObjectID
RecordID
SelectedRootFields[]
Optional MinCatalogRevision
```

Rules:

- object, record, and every selected field are required and non-blank;
- at least one field is selected;
- object and field identifiers use the existing ASCII identifier grammar and
  are at most 64 bytes; record input is opaque UTF-8 of at most 255 bytes;
- the submitted field list and the canonical deduplicated selection are each
  bounded at 512, so duplicate input cannot bypass admission or cause
  unbounded normalization work;
- the request is bounded by the 64 KiB canonical semantic measurement defined
  by the P1c envelope oracle; because the per-dimension limits bound the current
  largest structurally valid request at 34,720 bytes, this is a defensive outer
  cap rather than a second way to admit larger identifiers or field lists;
- relationship syntax and dotted paths are invalid;
- Runtime resolves names against the metadata snapshot bound at entry; the
  caller does not declare field types;
- duplicate selections normalize to one canonical metadata field;
- conflicting case variants that do not resolve uniquely are invalid;
- output fields sort by canonical field API name in ascending bytewise UTF-8
  order, independent of request order, maps, caches, or database column order;
- `MinCatalogRevision`, when present, is the only caller-selectable consistency
  requirement in v1. Runtime waits within the request deadline for a serving
  replica at least that revision or returns stale-state failure.

Org, principal, AppInstallation, permission, security level, and session facts
are not semantic request fields.

### 3.2 Success result

A success result contains:

```text
RecordID
Fields[]                 // deterministic canonical order
Receipts
```

The complete authorized result, including receipts, is bounded at 1 MiB under
the same canonical semantic measurement. Runtime returns
`RESOURCE_EXHAUSTED` and no fields when the full result would exceed it. This
semantic accounting projection is not a JSON public API or a future wire DTO;
P2 replayed the exact/one-over vectors through the generated codec and set
independent transport caps; the semantic accounting projection remains
transport-independent.

Each selected, readable, present field has exactly one typed value entry. A
selected, readable, explicitly null field has one entry with `Null=true` and no
value. A selected field absent from the stored record, or hidden by FLS, has no
entry. The response does not disclose which omission reason applied.

Unknown selected fields are `INVALID_REQUEST`; they are not treated as absent.
The future executable absent-value case must therefore use a field declared in
the bound schema but absent from the record. This tightens the P1b fixture,
whose minimal schema currently proves projection behavior but does not validate
its selection against declared fields.

The result is all-or-nothing. Runtime never returns some fields plus a limit,
deadline, stale-state, permission, or internal error.

## 4. Trusted request context

### 4.1 Authenticated transport/delegation facts

The authoritative interceptor receives the signed, short-lived delegation
owned by
[`runtime-trusted-delegation-contract.md` Section 4](runtime-trusted-delegation-contract.md#4-delegation-facts).
That section is the only authoritative delegation-field inventory. For this
operation, its post-intersection `Capabilities[]` must contain
`runtime.records.read-selected-root.v1`; OAuth scopes remain issuer inputs and
are not a second authority set in the data call. The delegation is
audience-bound to Runtime and bound to the caller workload and App installation.

At every RPC, Runtime revalidates:

- delegation signature, expiry, audience, and reuse/revocation binding;
- caller workload identity;
- session existence/revocation and principal activity;
- current Connected App state;
- `OrgID + AppInstallationID` authorization for that workload;
- scope/capability intersection including
  `runtime.records.read-selected-root.v1`;
- AuthEpoch/SecurityEpoch and security lease;
- object Read, RLS, and FLS inside the bound Runtime metadata/security view.

Current code already verifies JWT claims, the database session, revocation,
user activity, Connected App activity, and database-owned scope/App values in
`nexuscrm-auth/auth_service.go:475-543`. AppInstallation, workload delegation,
AuthEpoch, and SecurityEpoch are target-architecture requirements, not claims
that the current in-process path already implements them. Their single-owner
rules come from
`docs/design/nexuscrm-serviceification-target-architecture.md:278-307`,
`docs/design/nexuscrm-serviceification-target-architecture.md:375-385`, and
`docs/design/nexuscrm-serviceification-target-architecture.md:659-694`.
The proposed owner, issuance/admission order, persistence split, failure matrix,
and implementation gates for those deferred requirements are specified by
[`runtime-trusted-delegation-contract.md`](runtime-trusted-delegation-contract.md).
Until that ADR reaches Approved and its P6-D gate passes, this section remains
a semantic requirement rather than a production-authority claim.

### 4.2 Native RPC context

These facts use native gRPC/context propagation rather than semantic payload:

- required deadline and cancellation;
- request ID;
- W3C trace context and baggage allowed by observability policy.

Cancellation propagates to all Runtime work and database calls. Runtime must
not detach the record read onto `context.Background()`. A deadline already
expired at entry returns `DEADLINE_EXCEEDED`; explicit cancellation returns
`CANCELED`.

### 4.3 Forbidden authoritative inputs

Runtime must reject or ignore as non-authoritative:

- a raw user bearer token forwarded as Runtime authority;
- caller-provided permission/FLS/RLS maps;
- a caller-selected `SecurityContext` or bypass flag;
- OrgID, PrincipalID, workload, or AppInstallation supplied only in ordinary
  request fields or unverified headers;
- caller-provided Catalog/Security receipts presented as proof of authority.

The interceptor compares any diagnostic duplicate with the delegation and fails
closed on mismatch. L1 never constructs a `models.UserSession` as authority.

## 5. Value model

The semantic value is a closed tagged union. It contains no Salesforce DTO,
JSON-number convention, database driver value, or Go `interface{}` contract.

| Kind | Semantic representation | Required normalization |
|---|---|---|
| string | UTF-8 string | empty string is present |
| boolean | boolean | `false` is present |
| signed integer | signed 64-bit integer | zero is present; overflow fails |
| decimal | base-10 coefficient text plus non-negative scale | no float round-trip or exponent; stored scale is preserved, including `0.00` |
| date | calendar date | `YYYY-MM-DD`, validated Gregorian date |
| datetime | UTC instant with nanosecond precision | canonical RFC 3339 text ending in `Z` at semantic boundaries |
| reference identifier | opaque root identifier string | no target label/type/record expansion |
| explicit null | null marker with declared field kind | no value arm |
| absent | no field entry | covers stored absence and FLS omission without revealing which |

Empty string, `false`, integer zero, and decimal zero are never represented by
absence or null. A present value with the wrong kind is `INTERNAL_FAILURE`
because Runtime and its bound schema disagree; it is not coerced by L1.

P1c-M2a fixes the pre-wire decimal source of truth without changing the legacy
record value type. The SQL scanner preserves driver text byte-for-byte;
metadata hydration records an exact carrier for every DECIMAL-backed Double,
Currency, Percent, formula, and rollup field before producing the historical
`float64` value; and FLS projection copies a carrier only when its authorized
public field remains present. The carrier exposes canonical coefficient and
scale directly. The existing `contract.Records` adapter continues to strip the
internal carrier and return its legacy float value.

The selected-root implementation introduced by the projection-pushdown slice
must consume that carrier before the legacy adapter boundary. A present
DECIMAL-backed field with no valid carrier is an internal schema/storage
mismatch; it must not be reconstructed from `float64`. This paragraph does not
add an in-process capability, wire DTO, protobuf, or alternate database read
path.

P1b already exercises strings, booleans, integers, decimal text, date,
datetime, reference identifiers, null, absence, FLS omission, `false`, integer
zero, decimal zero, and empty string in
`nexuscrm-records/issue_tracker_conformance_test.go:24-70`.

## 6. Authorization and disclosure

The stable observable matrix is:

| Condition | Semantic result | Disclosure |
|---|---|---|
| record absent | `MISSING` | generic; no object/record existence detail |
| RLS denies existing record | `MISSING` | byte-equivalent semantic category and public projection to absent record |
| object Read denied | `FORBIDDEN` | generic object-read denial; no field/RLS detail |
| one selected field hidden by FLS | success with that field omitted | no indication whether absent or FLS-hidden |
| AppInstallation/workload unauthorized | `FORBIDDEN` | generic capability denial; do not reveal installation owner/state |
| invalid/expired/revoked delegation or session | `UNAUTHENTICATED` | generic reauthentication required |

Missing and RLS denial remain indistinguishable. Object Read remains
distinguishable from missing because current `prepareOperation` rejects it
before the repository lookup, while RLS maps to the same not-found path as a
missing row (`nexuscrm-records/persistence_bulk_ops.go:748-769`). P1b pins the
same golden outcomes at
`nexuscrm-records/issue_tracker_conformance_test.go:79-111`.

Cross-org and cross-AppInstallation requests fail before record lookup. Tests
must prove the repository adapter is not invoked on those failures.

## 7. Stable error and retry model

Applications branch only on category and structured safe details, never on
message text. Internal causes, SQL, topology, raw identifiers, token state, and
permission rules are log-only.

| Category | Safe details | Retry | New delegation? | Future gRPC mapping | CRM public projection | Fixture projection |
|---|---|---|---|---|---|---|
| `INVALID_REQUEST` | invalid request component; canonical field name only when safe | after correcting request | no | `INVALID_ARGUMENT` | 400 `INVALID_REQUEST`/`INVALID_FIELD` | conformance failure, not a read outcome |
| `UNAUTHENTICATED` | none beyond reauthenticate | after authentication | yes | `UNAUTHENTICATED` | 401 `INVALID_SESSION_ID` | `unauthenticated` |
| `FORBIDDEN` | generic capability/object-read denial | no automatic retry | only if authority changes | `PERMISSION_DENIED` | 403 `FORBIDDEN` | `forbidden` |
| `MISSING` | none | no automatic retry | no | `NOT_FOUND` | 404 `NOT_FOUND`, `Record not found` | `missing` |
| `CANCELED` | none | caller decides | no | `CANCELED` | no App payload after client cancellation | `canceled` |
| `DEADLINE_EXCEEDED` | none | caller policy; bounded | normally no | `DEADLINE_EXCEEDED` | sanitized 504 `UNKNOWN_EXCEPTION` | `deadline_exceeded` |
| `RESOURCE_EXHAUSTED` | violated limit kind and approved maximum; never actual secret size | only with smaller request or later capacity | no | `RESOURCE_EXHAUSTED` | 400 `LIMIT_EXCEEDED`; encoded request overflow may be 413 `INVALID_REQUEST` at edge | `resource_exhausted` |
| `INCOMPATIBLE` | protocol/capability required and supported ranges | after compatible rollout/routing | no | `FAILED_PRECONDITION` | sanitized 503 `UNKNOWN_EXCEPTION` | `incompatible` |
| `STALE_STATE` | stale axis plus required/served revision when safe | bounded retry on compatible replica | new delegation only for stale/revoked auth or security binding | `FAILED_PRECONDITION` | sanitized 503 `UNKNOWN_EXCEPTION` | `stale_state` |
| `UNAVAILABLE` | retry-after hint when known | yes, exponential backoff within original user budget | no unless delegation expires | `UNAVAILABLE` | sanitized 503 `UNKNOWN_EXCEPTION` | `unavailable` |
| `INTERNAL_FAILURE` | correlation/request ID only | no blind automatic retry | no | `INTERNAL` | sanitized 500 `INTERNAL_ERROR` | conformance failure |

The CRM mappings for missing and forbidden are observed current behavior in
nexuscrm-app-packs `records.go:1051-1061` and `query_errors.go:27-48`. Other CRM
mappings above are P1c design decisions owned by the future L1 adapter, not
claims about the current point-read handler.

Reads have no ambiguous commit outcome and need no idempotency key. Retrying a
read is allowed only under the table above and within the caller's total
deadline/retry budget. A retry never weakens `MinCatalogRevision` or security
requirements.

## 8. Consistency and receipts

At entry, Runtime binds one immutable execution view and never refreshes it
mid-operation:

```text
ProtocolVersion
CatalogRevision
SchemaGeneration
EngineGeneration
SecurityEpoch
CapabilityVersion(runtime.records.read-selected-root.v1)
```

The success response returns all six as receipts. A stable failure returns only
receipts known before the failure and safe to disclose; missing/RLS and FLS
results must not differ by receipt shape.

`MinCatalogRevision` is optional and monotonic. The caller cannot request an old
security view. Runtime always enforces at least the delegation SecurityEpoch and
the authoritative current minimum, with a valid security lease. SchemaGeneration
must be compatible with the bound CatalogRevision. EngineGeneration need not be
equal across builds, but it must advertise the required capability semantics.

`DefinitionVersion` is absent because this pure root read executes no caller-
selected flow, validation, lifecycle, or other immutable definition. If a later
read executes such a definition, that is a new capability decision.

These axes refine, rather than replace, the authorities in
`docs/design/nexuscrm-serviceification-target-architecture.md:621-694`.

## 9. Limits, deadlines, and owner-aligned gates

### 9.1 Historical pre-P1c-D evidence classification

| Dimension | Observed state at `a6c517f7e` | Pre-P1c-D status |
|---|---|---|
| selected fields | the selected-root path canonicalizes an unbounded slice; 256 and 257 both execute successfully | **BLOCKED: no approved maximum** |
| request bytes | point read is an HTTP GET and has no operation-level encoded-request cap | **BLOCKED: no wire-size measurement** |
| response bytes | selected-root returns a complete typed projection but enforces no response cap | **BLOCKED: no approved maximum** |
| object identifier length | metadata validates identifier grammar but not length (`nexuscrm-metadata/validation_service.go:1057-1062,1565-1568`) | **BLOCKED: no single enforced maximum** |
| field identifier length | same grammar-only validation (`validation_service.go:1111-1114,1565-1568`) | **BLOCKED: no single enforced maximum** |
| record identifier length | current schemas contain differing storage widths and the neutral adapter only requires a string | **BLOCKED: no single enforced maximum** |
| required deadline | target architecture requires one; current `http.Server` sets no read/write timeout (`backend/pkg/serverruntime/runtime.go:781-785`) | required, with no default; numeric maximum **BLOCKED** |

This table is retained as the baseline that P1c-D had to replace; it is not the
current decision state. Section 9.12 is authoritative. The reviewed fixture is
973 bytes on disk and its largest compact golden result
is 481 bytes. Those measurements prove only that the fixture is small; they do
not justify production maxima. Likewise, a future gRPC library default is a
transport safety net, not a product capacity contract.

### 9.2 Frozen qualitative behavior

- Every RPC must carry a deadline. There is no implicit/default deadline.
- A missing deadline is `INVALID_REQUEST`.
- Runtime executes each attempt under the earlier of the trusted caller
  deadline and the approved two-second attempt cap. The cap is a resource and
  cancellation bound, not a latency SLO or success guarantee.
- Every identifier, field count, encoded request, and encoded response is checked
  before expensive work or allocation where possible.
- Any exceeded bound returns `RESOURCE_EXHAUSTED` and no record projection.
- No truncation, pagination, streaming, or partial field set is allowed in v1.

### 9.3 Evidence and finite dispositions required for P1c-D

The evidence program had to run the same root-read operation through the
production adapter and either measure or finitely disposition:

1. current production CRM root-selection field counts and encoded value sizes at
   p50, p95, p99, p999, and observed maximum;
2. the largest installable current metadata object plus representative L2 custom
   fields, with the longest admitted object, field, and record identifiers;
3. request and complete authorized response encoded sizes for 1 field, each
   candidate field-count boundary, and one-over-boundary;
4. success, null/absent/FLS, missing, RLS, forbidden, and all scalar kinds;
5. end-to-end and Runtime service latency at representative concurrency,
   including p50/p95/p99/p999 and cancellation propagation;
6. a codec-independent semantic boundary vector plus an explicit reserved
   codec/framing budget below the proposed transport receive/send caps. P2
   subsequently replayed that exact vector through the reviewed generated codec
   before deployment; the result is measured headroom, not a semantic limit;
7. a chosen required maximum deadline tied to the route SLO and total retry
   budget, plus exactly-at and just-over tests.

The report must state dataset revision, app-packs revision, environment, command,
concurrency, sample count, raw artifact location, and selection/value shape.
M1 and M2d-A through M2d-C provide the reproducible execution evidence and
root-cause disposition. Public/anonymized aggregate evidence contains current
CRM pack and test2 metadata shapes, not tenant payloads or a private production
traffic histogram. That missing histogram is a compatibility input for the L1
route owner, not an open-ended blocker for an initial bounded Runtime contract:
the approved 512-field maximum covers the observed metadata maximum of 352 and
the pinned production CRM pack maximum of 39. Section 9.12 chooses every P1c
value and gives every later implementation/deployment value one owner and a
finite executable gate.

### 9.4 P1c-M1 reproducible evidence harness

P1c-M1 adds a test-only harness at
`nexuscrm-records/selected_root_capacity_evidence_test.go`, invoked by
`scripts/performance/run-selected-root-capacity-evidence.sh`. It is excluded
from the default build and production dependency closure; CI compiles it only
under `selected_root_capacity_evidence` with the reviewed P1b fixture snapshot.

At the M1 measurement revision, the measured path was the then-current real
`ContractService.Retrieve -> PersistenceService.Retrieve ->
RecordRepository.FindOne -> RLS -> FLS -> neutral conversion` path against an
isolated synthetic TiDB database. The report must retain two current-tree
limitations:

1. `RecordRepository.FindOne` selected `*`; root selection occurred in the fixture
   consumer after the adapter. Measurements therefore describe the real current
   adapter plus deterministic semantic projection, not future selected-column
   pushdown.
2. Metadata and permission repositories are deterministic public-service test
   seams. The reported database query count is the one real root repository
   query; it is not a cold-cache metadata/permission query count.

An optional, separate collector emits only anonymized numeric aggregates from
the selected environment: metadata field-count percentiles, identifier-length
maxima, and sampled public-CRM-table count. It never emits metadata names,
identifiers, records, or traffic payloads, and the fixture never reads that
database.

Before execution on the secret-bearing test2 runner, the downstream workflow
must prove that the exact NexusCRM revision is already merged to NexusCRM main.
Every JSON and Markdown artifact records NexusCRM, production app-packs, and
fixture revisions; environment and representativeness scope; TiDB/Go/OS/CPU/
memory/pool configuration; dataset; command; warmup/sample/concurrency grid;
tail latencies; sizes; queries; allocations; errors; cancellation; and
identifier probes.

The harness encodes compact semantic JSON only. It records this as a logical
size proxy and leaves generated-codec size and transport headroom unavailable.
At M1 time the generated codec did not yet exist. P2 subsequently replayed the
exact M1 semantic vectors before enforcing transport headroom. Likewise,
cancellation/deadline propagation does not select a maximum route deadline
without a separately owned route SLO and total retry budget. M1 added evidence
but did not itself change any then-`BLOCKED` status in this section.

### 9.5 P1c-M2b selected-root projection pushdown

P1c-M2b adds the current in-process data/projection implementation for the
semantic operation without adding it to `contract.Deps` or defining a
transport. Trusted delegation, consistency receipts, numeric admission, and
wire error mapping remain future slices. The execution path is:

```text
records.ContractService.ReadSelectedRecord
-> records.PersistenceService.ReadSelectedRecord
-> analytics.QueryService.ReadSelectedRootProjection
-> permissions.BuildRLSResult
-> persistence.QueryRepository.Find
-> metadata-aware scalar hydration
-> deterministic authorized selected-root result
```

Records remains the owner of object Read, selected-field metadata validation,
canonicalization, FLS, null/absence semantics, and the typed semantic result.
Analytics remains the owner of query-level RLS planning. Persistence remains
the owner of SQL lowering and storage hydration. No selected-root code
reconstructs the point-read permission dependencies or calls
`CheckRecordAccess` on a partial row.

The database work closure is narrower than a post-fetch permission projection:

- the SQL `SELECT` list contains only `Id` plus canonical readable requested
  fields;
- `OwnerId`, criteria fields, folder/parent fields, target-record fields,
  sharing tables, deletion state, and other policy inputs occur only in the
  authoritative RLS/query predicates or subqueries that need them;
- the response builder iterates only the canonical readable requested fields,
  so `Id` and every policy-only input remain internal unless explicitly
  selected and authorized;
- a reference selection is hydrated only as its root identifier. This path
  does not call lookup-name, relationship, child, compound, or virtual-field
  hydration;
- if FLS removes every requested field, the repository still performs an
  `Id`-only existence/RLS query and never falls back to an empty projection or
  `SELECT *`.

`nexuscrm-persistence/query_selected_root_projection_test.go` pins the actual
SQL shape with `OwnerId` evaluated in `WHERE` but absent from `SELECT`.
`nexuscrm-analytics/selected_root_projection_test.go` pins the prepared RLS
result, exact column closure, Id-only all-FLS-hidden case, and exact-decimal
hydration without lookup work. `nexuscrm-records/selected_root_read_test.go`
pins canonical ordering, typed scalars, false/zero/empty, null versus absence,
FLS omission, missing/RLS masking, forbidden, pre-entry and in-flight
cancellation, and failure when a DECIMAL-backed value lacks the exact carrier.

This slice removed full-row width from the selected-root work model. At M2b
merge it approved no field count, identifier, semantic byte, response byte,
deadline, concurrency, or transport limit; those inputs proceeded to the later
M2c/M2d evidence and Section 9.12 decision.

The post-merge M2b review hardening preserves two existing engine invariants.
Selected-root obtains its query RLS through `QueryService.readRLSResult`, so
ordinary user reads still use `BuildRLSResult` while `SystemContext` and an
authorized scoped-internal read retain the same RLS bypass as `QueryWithSpec`.
Storage boolean hydration dispatches on `schemautil.EffectiveFieldType`, so
physical, formula-return, and rollup-return boolean fields normalize through
one rule before strict selected-root typing. These corrections change no
limits, transport, public route, or legacy `contract.Records` behavior.

### 9.6 P1c-M2c candidate envelope validation

M2c adds a test-only, ordinary-CI candidate oracle at
`nexuscrm-records/selected_root_envelope_candidate_test.go` and a reviewed
machine-readable golden under `nexuscrm-records/testdata`. It uses compact,
deterministic semantic JSON only to create exact boundary vectors; its request
and response structs are measurement projections, not wire DTOs. It imports no
protobuf or gRPC package and changes no production admission behavior.

The initial candidates produce these reproducible facts:

| Candidate | Exact / one-over evidence | M2c result |
|---|---|---|
| 256 selected fields | the current selected-root path returns 256 and also 257 fields | viable as a **new** limit; not current behavior |
| 64 KiB semantic request | grammar-valid 256-field vectors encode to exactly 65,536 and 65,537 bytes; taking all independent 255-byte identifier maxima yields 66,655 bytes | viable active cross-limit; not current behavior or wire size |
| 1 MiB complete response | a 256-field string response including representative receipts encodes to exactly 1,048,576 and 1,048,577 bytes | viable semantic cap; the receipt spelling remains non-wire measurement data |
| 255-byte identifiers | logical 255/256-byte vectors exist, and metadata columns store API names in `VARCHAR(255)` | the single 255-byte proposal is **rejected by current storage evidence** for object, field, and record IDs |
| 5-second required deadline | exact 5s and 5s+1ns vectors exist; the current path accepts both a missing deadline and 5s+1ns | still blocked on a route SLO and total retry budget |
| 128 KiB receive / 2 MiB send | reserves 64 KiB and 1 MiB respectively above the semantic caps | viable reserved budgets, but not measured codec headroom |
| compression disabled | no codec existed at M2c | P2 later enforced disabled request and response compression |

The identifier failure is not a wording issue. M1 proved TiDB physical table
and column identifiers accept 64 bytes and reject 65. Current object creation
uses `ObjectMetadata.APIName` directly as `TableDefinition.TableName`, and
current field creation initially uses `FieldMetadata.APIName` directly as the
column/`PhysicalName`. There is no independent physical object-name mapping.
Therefore a 255-byte object/field API promise cannot be approved from the
metadata `VARCHAR(255)` width. Record ID has a separate contradiction: current
generic object creation provisions `Id` as `VARCHAR(36)` and ordinary record
inserts generate 36-byte UUIDs, while metadata Flow/FlowDefinition rows use an
18-byte Salesforce-compatible generator and older/current schemas contain
other widths.
M1's synthetic `VARCHAR(255)` probe proves only that one synthetic column shape
can store 255 bytes. It does not establish the installed-object owner or a
public maximum. P1c-D must choose evidence-backed per-kind limits and prove the
installed-schema compatibility/migration, or keep the dimensions blocked. M2c
does not add a new naming or record-ID storage design.

The post-merge owner guards derive these facts through the actual paths.
`nexuscrm-metadata/identifier_storage_owner_test.go` calls
`MetadataService.PrepareTableDefinition` to prove default object/field physical
names and generic `Id VARCHAR(36)`, and separately pins the metadata-flow
three-byte key-prefix plus fifteen-digit generator.
`nexuscrm-records/record_id_owner_test.go` calls the ordinary insert-side
`generateSystemFields` path and proves it emits a canonical 36-byte UUID. If an
owner changes, ordinary CI forces the M2c evidence/golden to be re-evaluated
instead of silently retaining stale conclusions. The external TiDB 64/65
boundary remains M1 probe evidence, not a Go constant.

The wire-size circular dependency was resolved by ownership rather than by
pre-generating protobuf. P1c-D approved semantic caps plus minimum reserved
transport budgets. P2 then replayed the exact M2c vectors through the first
reviewed codec and enforced the configured transport caps. Before that replay,
the budgets were only **reserved codec/framing budget**, never measured
headroom; the P2 result does not turn transport limits into semantic limits.

M2c therefore validated the field-count, semantic-byte, and
reserved-transport candidates, rejected the single 255-byte identifier claim,
and left the per-kind identifier limits plus five-second deadline unratified at
that stage. Section 9.12 records the later P1c-D decisions; this historical
candidate slice itself changed no production enforcement.

### 9.7 P1c-M2c-E structurally valid envelope

M2c-E keeps the M2c golden as historical candidate evidence and adds a separate
ordinary-CI oracle at
`nexuscrm-records/selected_root_valid_envelope_candidate_test.go`. It corrects
three assumptions without changing production admission:

1. Object and field API identifiers use the existing ASCII grammar and map
   directly to TiDB physical names. Their candidate maximum is therefore 64
   bytes, matching the measured 64/65 physical boundary. No logical-to-physical
   naming layer is introduced to preserve the rejected 255-byte proposal.
2. Record identifier is a different resource fact. The managed L0 catalog has
   133 string primary-key owners at `VARCHAR(255)` and three numeric `BIGINT`
   owners (a signed `BIGINT` needs at most 20 ASCII bytes). Generic object
   records use 36-byte UUIDs, metadata Flow records use 18-byte IDs, and the
   longest shared schema-package ID generator at maximum 64-byte API names emits
   171 ASCII bytes. These facts make 255 bytes a candidate opaque **read-input
   bound**, not a claim that every object can store 255 bytes. It
   requires no physical-column introspection: a value over 255 bytes is a
   request resource failure before metadata/repository access, while a shorter
   value that cannot name a row in a narrower object follows the ordinary
   authorized lookup and returns `MISSING`. Runtime does not disclose the
   object's physical ID width.
3. The 256-field candidate does not cover the anonymized test2 metadata maximum
   of 352 fields. The revised candidate is 512 selected fields. This covers the
   observed shape. M2d-A later measured the post-M2b 512-field path, and P1c-D
   approves the resulting 512-field semantic maximum in Section 9.12.
   The pinned production CRM pack has 21 objects and a declared maximum of 39
   fields; test2 has 239 metadata objects, p999 287 fields, and maximum 352.
   These are shape observations, not actual selected-field traffic.

The current catalog owner census also includes fixed-width `CHAR(n)` string
primary keys. Application navigation adds one `CHAR(64)` receipt ID owned by
its SHA-256 hex generator, bringing the current golden to 176 string owners.
The maximum string width remains 255; this adds no record-input capacity and
does not change the historical evidence or approved admission bounds.

With 512 selected fields, 64-byte object/field names, a 255-byte record input,
and the maximum catalog revision, compact semantic JSON is 34,720 bytes. The
corresponding generic-UUID and metadata-Flow requests are 34,501 and 34,483
bytes. One over the field-count candidate is 34,787 bytes; one over any single
identifier candidate is 34,721 bytes. Consequently the 64 KiB semantic request
candidate is a defensive outer cap rather than the active largest-valid-request
boundary. The reviewed 65,536/65,537-byte M2c vectors remain adversarial
envelope evidence, not structurally valid v1 requests.

The 512-field response with maximum field-name and record-input widths has a
54,301-byte base. Extending one authorized string value produces structurally
valid complete responses at exactly 1,048,576 and 1,048,577 bytes, so the 1 MiB
response candidate retains a valid exact/one-over pair after the field-count
revision.

The machine-readable golden derives the system-catalog owner counts and maximum
width through `schemacatalog.ManagedTableDefinitions`; changes to that owner
inventory force ordinary CI review. The two test2 evidence runs remain
`test2-29156004886-1` and `test2-29158105319-1`. Their tenant-neutral,
numeric-only aggregate snapshot, run IDs, artifact IDs, measured NexusCRM
revision, and complete `result.json` SHA-256 values are checked in under
`tests/performance/selected-root-read/testdata`; the oracle derives observed
shape from that snapshot and verifies its app-packs/fixture tuple against
`revisions.env`. The authoritative ordinary-CI snapshot intentionally contains
no L2 repository or workflow URL; the historical learned log retains the
non-authoritative operator links. M2c-E proposes candidates only:
no current validation, storage, route, protobuf, gRPC, service, transport, or
error behavior changes in this slice.

### 9.8 P1c-M2c-S route budget and retry ownership

M2c-S closes the ownership and budget arithmetic needed to test a deadline
candidate. It does not approve the candidate, select a consumer, or change the
current HTTP route. If C0 selects an sfcrm route for a Runtime capability, that
L1 route owner owns the end-to-end user-route SLO and its total retry policy.
Gateway propagates the earlier trusted deadline and may enforce a coarse generic
routing ceiling, but does not retry the semantic read. Runtime owns only the
single-attempt cap, cancellation, admission, and load shedding. This prevents
three layers from independently spending the same latency budget.

The M2c-S candidate, unapproved at that stage, was:

| Budget fact | Candidate | Classification |
|---|---:|---|
| end-to-end route budget | 5 seconds | new ADR proposal |
| Runtime attempt cap | 2 seconds | derived new proposal |
| attempts / retries | 2 / 1 | new ADR proposal |
| retry backoff | full jitter, at most 250 ms | new ADR proposal |
| reserved route work | 750 ms | derived remainder for L1/Gateway request and response work |

The worst case closes exactly: `2 * 2s + 250ms + 750ms = 5s`. Increasing each
attempt by one nanosecond yields 5 seconds plus 2 nanoseconds; allowing one
additional retry yields 7.25 seconds. A retry begins only after its backoff and
only if at least one full 2-second attempt plus the 750-millisecond route-work
reserve remains. The original route context remains the parent of every attempt,
so scheduling and other overhead can suppress a retry but can never extend the
route deadline. A shorter trusted upstream deadline always wins.

Only `UNAVAILABLE` and an eligible `STALE_STATE` may use the one retry.
`STALE_STATE` requires routing to a compatible replica; delegation is refreshed
only when the stale axis is authorization/security. A retry never weakens
`MinCatalogRevision`, `SecurityEpoch`, capability, or any other consistency
requirement. `CANCELED`, `DEADLINE_EXCEEDED`, `FORBIDDEN`, `INCOMPATIBLE`,
`INTERNAL_FAILURE`, `INVALID_REQUEST`, `MISSING`, `RESOURCE_EXHAUSTED`, and
`UNAUTHENTICATED` do not receive this automatic route retry.

The external HTTP client is not required to manufacture a Runtime RPC
deadline. After cutover, the sfcrm AppService route owner must always create an
explicit Runtime attempt deadline within the earlier of its route budget and
any trusted upstream deadline. A Runtime call without a deadline remains
`INVALID_REQUEST`; a Runtime attempt beyond the eventual approved cap is
rejected or clamped according to the P1c-D decision.

Current behavior remains materially different and is recorded, not hidden:
at app-packs `bb138eff`, `dialects/dialect-sf-crm/records.go:46-61` passes its
context to `contract.Records.Retrieve` but adds no route deadline or retry, and
at NexusCRM `1968d182`, `backend/pkg/serverruntime/runtime.go:781-785` sets only
`Addr` and `Handler` on `http.Server`, with no `ReadTimeout` or `WriteTimeout`.
The ordinary-CI oracle at
`nexuscrm-records/selected_root_route_budget_candidate_test.go` and its JSON
golden pin the proposed neutral owner split, retry categories, and
exact/one-over arithmetic. Review of the production diff, not a copied test
literal, proves that this slice changes no runtime behavior. M2d-A and M2d-C
subsequently validated the current post-M2b path and retained the independent
512-field deadline outcomes as a production-cutover gate; P1c-D alone may
approve or reject the candidate.

### 9.9 P1c-M2d-A post-pushdown evidence harness

M2d-A extends the existing test-only performance framework without changing or
relabeling M1 history. The separate
`scripts/performance/run-selected-root-m2d-a-evidence.sh` entry point reuses the
reviewed revision pins, synthetic scratch-database ownership, artifact
conventions, and tagged production-closure guard. Its measurement test executes
the current post-M2b path from `ContractService.ReadSelectedRecord` through
`QueryRepository.Find`; it does not use the fixture-only value normalizer or
the historical `Retrieve`/`FindOne` wildcard path.

Before timed cells, the harness records two distinct readiness phases: 5,000
ordinary 39-field reads at concurrency 1 to exercise the sequential
test2/serverless startup path, followed by 5,000 512-field reads at concurrency
16 to warm the wide path and database pool. The startup phase is exactly 5,000
attempts: the full cold distribution remains in the artifact; only early
`deadline-exceeded` outcomes are admissible; every other early error class
fails; and timed cells require the final 1,200 attempts to have zero errors and
p99 below the 250 ms diagnostic readiness target. This is not a production SLO.
Run `29171276326` proved that the
wide concurrent phase alone completes too quickly to stabilize the subsequent
single-request cells: its first 15-field/c1 cell remained cold and the following
39-field/c1 cell captured the transition. Run `29173225117` then proved that
requiring the entire bounded cold-start phase to be error-free rejects an
otherwise observable convergence path. Readiness therefore cannot be inferred
from concurrent query count alone or from aggregate cold-window errors. The A1
load matrix is the explicit
`1,15,39,256,512,513` workload set: smallest diagnostic, ordinary CRM shapes,
historical candidate, current candidate, and one-over. Each cell uses 1,200
samples, the minimum declared count that gives p999 an observed rank.
It then uses a recorded deterministic seed to shuffle field shapes within
ascending concurrency tiers `1,4,16,64`. This reduces fixed-order bias while
ensuring that any error stops all later, higher-load tiers. Candidate inputs
retain the pinned CRM pack distribution and the reviewed/current tenant-neutral
test2 p50/p95/p99/p999/maximum distribution as report evidence; those
distributions are not expanded into redundant performance cells.

The success-capacity dataset uses physically present and readable root fields,
so the 512-field cell measures a complete 512-field authorized projection.
Declared-but-absent and FLS-hidden cases remain semantic omission/fault inputs
for the golden and M2d-B matrix; adding them to the success workload would
either create a schema/storage mismatch or reduce the complete response width.
Every successful load read asserts that the complete authorized projection
contains exactly the selected-field count.

The report keeps measurement ownership explicit:

- adapter latency covers the current in-process Runtime-equivalent semantic
  operation, and end-to-end harness latency additionally covers deterministic
  semantic response encoding;
- database query count covers the real `QueryRepository.Find` call while
  metadata and permission repositories remain deterministic public-service
  test seams;
- concurrency 16 evaluates the unapproved admission target, while concurrency
  64 is only a saturation probe of the current unadmitted path;
- retry amplification is derived from measured queries per single attempt and
  the M2c-S two-attempt candidate. The harness executes no retry;
- the two-second context deadline evaluates the unapproved Runtime-attempt
  candidate and changes no production deadline behavior.

M2d-A is a performance-modeling gate, not a demand that the current monolith
already satisfy a final production SLO. The harness records opt-in process-local
stage observations for metadata/object security, selection normalization, FLS,
projection planning, RLS, repository preparation, SQL execution, raw row scan,
storage hydration, typed projection, and semantic serialization. It also
records GC, heap, goroutine, connection-pool pressure, query count, allocations,
and tail latency for explicit 15/39/256/512-field shapes. This diagnostic
observer is neither a Runtime capability nor a wire/contract surface; request
semantics never depend on it.

Initial hypotheses are deliberately unapproved: 15/39-field concurrency-16
p99 below 250 ms, 512-field concurrency-16 p999 below one second, every
concurrency-16 sample below the two-second attempt candidate, one database query
per attempt, and no pool wait at concurrency 16. A miss is evidence to profile,
not permission to weaken fields, permissions, or the environment.

The decision distinguishes three outcomes. One-RPC/query fan-out, cost that
grows without a field bound, uncontrolled queues/leaks, retry collapse, or an
optimization that required semantic contract changes would have blocked P2 at
that gate and reopened the boundary. A stable one-query boundary with slow SQL,
hydration, permission,
serialization, or allocation remains an internal Runtime optimization problem:
the semantic contract may proceed toward a no-traffic skeleton after P1c-D, but
production cutover remains blocked on its later SLO gate. Adequate measured
headroom allows the normal M2d-B/P1c-D sequence. After the baseline, each
optimization loop profiles one largest stage, fixes it at its existing owner,
and reruns the identical workload before the learned log records the result.

The final M2d-A evidence is test2 run
[`29174439835`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/actions/runs/29174439835),
artifact `8254639111`, artifact SHA-256
`7029e82d2a86af6953b9cf4b5fc2916e740619257fbb12b239fa1f069a99b54d`.
It pins NexusCRM
`849c98281391f046b77c82ad0df59292dee2f722`, app-packs
`bb138effbe9c2857db432224892c232e14bddf80`, and issue-tracker fixture
`ec2ed3b2f0501d749f7a2b2eac1a86bbeba506b8`. Both readiness phases converged;
all 24 cells and 28,800 timed reads completed with zero errors, exactly one
database query per read, and zero pool wait at concurrency 16. The 512-field
concurrency-16 cell observed p999 263.284 ms and maximum 270.103 ms; the largest
concurrency-16 maximum, at 513 fields, was 724.188 ms. Concurrency 64 remained
error-free but exposed saturation: the 512-field cell observed p99 1.168 s and
maximum 1.894 s.

The ordinary-shape diagnostic did not meet its unapproved target: the
39-field/concurrency-16 cell observed p99 535.439 ms against the provisional
250 ms hypothesis. Its SQL p99 was 534.395 ms while typed projection was
0.414 ms, so the measured tail is inside the database/runtime implementation,
not evidence of RPC or query fan-out. Allocations grew from approximately
335 KiB/read at one field to approximately 1.2 MiB/read at 512/513 fields;
that is a concrete Runtime optimization target, not proof of unbounded growth.
M2d-A therefore reaches decision category 2: the selected-root boundary shape
is viable, but SQL tail and allocation work remain before production cutover.
This evidence approves no field, byte, deadline, admission, retry, transport,
or production-SLO limit; those decisions remain owned by P1c-D and the later
transport/cutover gates.

At M2d-A time, Gateway, AppService route work, split-process scheduling,
generated-codec and transport bytes, production admission/load shedding, and
automatic retries did not exist on this path and were explicitly unmeasured.
The 750 ms route-work reserve remains a design allocation unless a
representative current CRM route measurement closes it; otherwise the real
owner must validate it at the V1 cutover gate. M2d-A evidence cannot be
presented as future
Gateway-to-worker end-to-end latency, and only P1c-D may approve a limit.

### 9.10 P1c-M2d-B current-seam correctness evidence

M2d-B starts from NexusCRM `5a70ec5041d76ac438dd6dd38ac038766ae53088`
and tests only the executable in-process chain. It adds no transport,
delegation, epoch, replica, admission, or issue-tracker production artifact.
The ordinary CI gate `scripts/ci/test-selected-root-m2d-b.sh` runs the records,
analytics, and SQL-repository seams normally and under the race detector, then
runs five-second mutation budgets for identifier/selection and typed-value fuzz
targets.

The evidence found and fixed two correctness classes rather than merely adding
tests. First, cancellation could race an empty repository result and be
misreported as `MISSING`; cancellation is now checked after repository return,
after storage hydration, after the records projection seam, and after typed
projection, so a canceled/deadline-exceeded operation returns no partial
record. Already-expired deadlines stop before RLS or repository access. Second,
the shared SQL row scanner did not inspect terminal `rows.Err()`, which could
turn a mid-stream driver failure into a successful partial result. The scanner
now propagates that error for every consumer.

Repository and projection failures are classified as internal conditions and
retain their cause for operator-side unwrapping; this in-process slice added no
response serializer, and the subsequently generated transport emits only the
Section 7 safe details. SQL rows close on
success and terminal scan failure; cancellation returns the sql.DB connection
to `InUse == 0`. Sixty-four simultaneously blocked reads all settle after
cancellation with zero in-flight calls. Repeated reads allocate and release
64 MiB of projection payload with no more than an 8 MiB post-GC live-heap
increase. Existing semantic tests continue to cover canonical ordering,
duplicate selection, exact decimals, false/zero/empty values, null versus
absence, FLS omission, missing/RLS masking, forbidden, and metadata/value-kind
mismatch.

This closed M2d-B only for then-current in-process behavior. At that time,
generated-codec N/N-1, wire-size, and compression behavior remained P2; real
replica admission and process failure remained P3; and authoritative
delegation, cross-org, cross-AppInstallation, revocation, and security/catalog
epoch behavior remained P6. Those implementation phases subsequently
completed; request-bound Catalog metadata still belongs to P7. Section 9.11
closes the 39-field/concurrency-16 anomaly as
timed connection-establishment contamination in the evidence harness. The
independent 512-field/concurrency-16 two-second deadline outcomes remain a
measurable production-cutover gate. Neither M2d-B nor M2d-C approves performance
or any numeric contract value.

### 9.11 P1c-M2d-C SQL-tail root-cause loop

The final M2d-A artifact contains a stronger correlation than the original
`SQL-dominated` summary recorded. The 39-field/concurrency-16 cell was the first
timed c16 cell. Its pool contained four open connections before timing and 16
afterward; SQL p99 was 534.395 ms. Every later c16 cell began with 16 open
connections. The final 15-field/c16 cell then observed SQL p99 67.578 ms. The
same run's preceding 512-field/c16 readiness phase also observed p99 195.156 ms
across 5,000 reads. Field count therefore does not explain the isolated tail.

The harness supplied the missing causal mechanism: its declared 50-read
per-cell warmup was a sequential loop and ignored the cell concurrency. The
ascending c1/c4 tiers ran long enough for the database/sql five-minute
connection lifetime to reduce the previously warmed c16 pool; the sequential
warmup could not restore it. Timed 39-field/c16 samples therefore included
opening 12 remote database connections and their TLS/session setup. Zero pool
wait does not disprove this: database/sql opens new connections for callers
without first recording a wait when capacity is available.

M2d-C corrects only this evidence owner. Artifact schema `p1c-m2d-a.v5` runs
each untimed cell warmup at the declared concurrency with at least one warmup
request per worker, records pool-open and lifetime/idle-close counters before
and after warmup and timing, and fails closed unless the timed window begins
with at least the declared concurrency in open connections. Runtime, SQL,
authorization, projection, and contract semantics are unchanged.

The first v4 test2 rerun stopped before the matrix. Its 5,000-request
512-field/c16 readiness phase issued exactly one query per attempt but observed
two deadline-exceeded outcomes in the final 1,200 requests. That is independent
evidence that the candidate two-second attempt cap is not a production
guarantee; it is retained as a measurable production-cutover gate rather than
weakened, retried away, or attributed to initial connection establishment.

Schema v5 therefore adds a reviewed `m2d-c-sql-tail` mode to the same harness.
It preserves the 5,000-request startup convergence check, then runs only the
identical 1,200-request 39-field/c16 timed cell after concurrency-aligned
warmup. This focused diagnostic makes no full-matrix, wide-readiness, SLO, or
limit claim. Its purpose is to resolve the original anomaly without allowing a
separate 512-field readiness failure to hide the relevant pool/SQL evidence.
Its machine-readable completion scope is limited to that slice; its hypothesis
set contains no 15-field, 512-field, or all-c16 verdict. The artifact also
carries the immutable failed-run provenance and 512-field/c16 two-second tail
as an explicit open retained production-cutover gate.

The immutable focused rerun is downstream test2 run
[`29180294181`](https://github.com/pingcap-inc/nexuscrm-pingcap-pack/actions/runs/29180294181),
artifact `8256296025`, archive SHA-256
`e2e4d82ed1521b8d3d151831a67b3b380ab361fe0b1689f6e91530a7159a3804`.
It used NexusCRM `34e82a93feef1f248fb6da3b0077c7751f64dcc6`, app-packs
`bb138effbe9c2857db432224892c232e14bddf80`, fixture
`ec2ed3b2f0501d749f7a2b2eac1a86bbeba506b8`, 1,200 timed requests,
39 selected fields, concurrency 16, and the unchanged two-second diagnostic
deadline.

After the long sequential startup phase the pool contained one connection.
Concurrency-aligned untimed warmup restored 16; the timed window began and
ended with 16, with zero lifetime/idle-time closures and zero pool wait. All
1,200 attempts issued exactly one query and completed without error. SQL p99
was 59.638 ms and end-to-end p99 was 61.179 ms, versus 534.395 ms and
535.439 ms in the contaminated run: reductions of 88.84% and 88.57%
respectively. End-to-end p999 was 73.224 ms and maximum was 74.063 ms.

This verifies the Loop 1 root cause: the isolated old tail came from timed
connection/TLS/session establishment in the evidence harness, not selected
field count, the SQL shape, or the selected-root contract. M2d-C is complete;
no Runtime/query optimization or contract change is warranted by that anomaly.
The inherited 512-field/c16 observation remains open and machine-readable: two
of 5,000 reads exceeded the diagnostic two-second deadline in the prior run's
final 1,200. That is a production-cutover route-SLO/attempt-budget gate, not a
reason to reopen the contract shape or a basis for approving a production SLO
or numeric limit in M2d-C. Section 9.12 records the subsequent P1c-D decision.

### 9.12 P1c-D final decision

P1c-D separates capability semantics from wire implementation, replica
configuration, and L1 route policy. `APPROVED` freezes a v1 semantic invariant;
the named later phase implements and verifies it. `DEFERRED` is not an unknown
or implicit default: it records the sole owner, current candidate, and finite
gate that must choose the deployment value. No item remains `BLOCKED` for P2.

| Dimension | Decision | Normative meaning | Enforcement / remaining gate |
|---|---:|---|---|
| selected root fields | **APPROVED: 512** | at most 512 submitted entries and at most 512 canonical unique fields; duplicates within the bound normalize deterministically | P2 wire/server validation before metadata or repository access |
| semantic request | **APPROVED: 64 KiB** | defensive semantic outer cap, not wire size and not the active largest-valid v1 shape; the largest current valid vector is 34,720 bytes | P2 canonical semantic-size and exact/one-over validation |
| complete semantic response | **APPROVED: 1 MiB** | includes the full authorized projection and required receipts; overflow is `RESOURCE_EXHAUSTED` with no partial result | P2 canonical semantic-size and exact/one-over validation |
| object identifier | **APPROVED: 64 ASCII bytes** | existing identifier grammar plus direct TiDB physical naming | P2 request validation before metadata or repository access |
| field identifier | **APPROVED: 64 ASCII bytes** | existing identifier grammar plus direct TiDB physical naming | P2 request validation before metadata or repository access |
| record identifier | **APPROVED: 255 UTF-8 bytes** | opaque read-input resource bound only; it does not promise that every object's authoritative ID column stores 255 bytes | P2 request validation before metadata or repository access; an in-bound impossible ID follows authorized lookup and returns `MISSING` |
| explicit attempt deadline | **APPROVED: required** | absence is `INVALID_REQUEST`; a shorter trusted upstream deadline always wins | P2 semantic vectors and P3 server enforcement |
| Runtime attempt cap | **APPROVED: 2 seconds** | hard execution/cancellation cap per attempt, not a latency SLO and not a promise that every maximum-shape read succeeds | P3 server enforcement and cancellation tests; production route cutover must close the retained 512-field tail |
| fail-fast admission | **APPROVED** | excess work is rejected as `RESOURCE_EXHAUSTED`; Runtime must not create an unbounded queue | P3 real-replica admission/load-shedding proof |
| v1 transport compression | **APPROVED: disabled** | no request or response compression; enabling it later requires an explicit capability/security decision | P2 client/server transport configuration and oversized-message tests |
| sfcrm L1 route budget | **DEFERRED; 5-second candidate** | L1 route policy, never a generic L0 Runtime SLO | P4/P5 real-route evidence from Gateway/AppService overhead and the retained maximum-shape tail |
| sfcrm L1 automatic retries | **DEFERRED; one-retry candidate** | only `UNAVAILABLE` and eligible `STALE_STATE` are semantically retryable; all work remains inside the original parent deadline | P4/P5 proves route arithmetic and absence of retry amplification |
| per-replica concurrency | **DEFERRED; 16 candidate** | deployment/admission configuration, not protocol semantics | P3 deployment configuration chosen from DB pool, queue, memory, cancellation, and load-shedding evidence |
| transport receive/send | **DEFERRED; 128 KiB / 2 MiB candidates** | transport receive/send ceilings, not semantic request/response maxima | P2 generated-codec exact/one-over replay and client/server configuration |

The two-second decision deliberately does not reinterpret the evidence. Focused
39-field/c16 evidence proves the old 535 ms p99 was benchmark connection setup,
but a separate run still observed two deadline expirations among 5,000
512-field/c16 readiness reads. A maximum execution budget can be approved
without claiming a production latency SLO; traffic cutover cannot. Any future
selected-root route must demonstrate that it meets its chosen SLO and retry
budget at the approved semantic maximum, or change its L1 route policy/capacity
plan. It may not silently increase the Runtime cap, drop 512-field compatibility,
retry ordinary reads, or weaken authorization/projection work.

The ordinary-CI decision oracle is
`nexuscrm-records/selected_root_contract_decision_test.go` with
`testdata/selected_root_contract_decision_golden.json`. It derives approved
semantic values from the M2c-E envelope and the Runtime cap from M2c-S, pins the
APPROVED/DEFERRED split, and requires every deferred value to retain one owner
and one finite gate. The oracle changes no production admission, deadline,
route, transport, or dependency behavior.

That oracle and the table above intentionally preserve the decision state and
phase names at P1c-D approval time. Later implementation does not rewrite that
historical evidence: P2 subsequently implemented the 128 KiB receive and 2 MiB
send caps plus compression-disabled behavior, and P3 implemented bounded
fail-fast admission mechanics. The historical `P4/P5 sfcrm` route budget,
retry, and 512-field tail remain attached to a future exact selected-root
consumer; they do not transfer to C0's different record-access capability.
Record-access must approve and verify its own route budget, retry, capacity, and
performance envelope. Deployment concurrency remains deferred to the owning
deployment/cutover decision. This paragraph is the sole mapping from the P1c-D
oracle to the current #3555 phase names.

## 10. Compatibility

- Protocol major v1 servers accept clients at current minor `N` and previous
  minor `N-1`; clients are tested against servers at `N` and `N-1`.
- Required capability negotiation happens before execution. Absence or an
  unsupported capability version is `INCOMPATIBLE`, never a best-effort fallback
  to a different read path.
- Unknown optional request fields are ignored only when their declared semantics
  say omission is backward-compatible. Unknown required behavior fails
  `INCOMPATIBLE`.
- Clients ignore unknown optional response fields. They must fail closed on an
  unknown value kind, error category, required receipt, or capability major.
- Adding an optional field, receipt, or safe error detail is additive. Changing
  authorization, omission/null semantics, value meaning, ordering, missing/RLS
  masking, or retry classification is breaking.
- A breaking semantic change creates a new capability major and, when wire
  compatibility requires it, a new service/version. Existing v1 behavior remains
  available through the declared migration window.
- Exact build SHA equality is forbidden as compatibility. Protocol range,
  capability version, EngineGeneration compatibility, and receipts decide.
- Runtime readiness is false for an org/revision when the replica cannot serve
  the required EngineGeneration/capability, CatalogRevision, SchemaGeneration,
  or SecurityEpoch. Traffic is not admitted and no legacy semantic fallback is
  selected inside the request.

## 11. Executable acceptance matrix

The acceptance matrix is cumulative. P2/P4 implemented the generated-wire and
separate-process portions against the dormant CRM L1 adapter and the CI-only
issue-tracker fixture; P6 implemented the trusted-delegation and isolation
portion on the real Runtime path. The same vector IDs and expected semantic
results must be retained; only public L1 projection assertions may differ. C0
proved that the dormant adapter has no exact selected-root production route, so
passing this matrix does not assert production traffic ownership.

| Case | Required assertion |
|---|---|
| one-RPC budget | exactly one Runtime data RPC; zero metadata/policy/lookup L1-to-Runtime calls; internal DB query count reported separately |
| typed values | string, boolean, signed integer, scale-preserving decimal, date, datetime, reference ID |
| false/zero/empty | all returned as present typed values |
| null versus absent | explicit null entry differs from omitted declared field |
| FLS omission | hidden selected field omitted; other selected fields succeed |
| missing/RLS | byte-equivalent semantic category and public projection |
| forbidden | object Read denial distinguishable from missing |
| cancellation | pre-entry and in-flight cancellation stop adapter/database work |
| deadline | already-expired and in-flight expiry produce `DEADLINE_EXCEEDED`, no partial result |
| ordering | shuffled/duplicate selection and map insertion order yield identical canonical output |
| field-count limit | zero, one, maximum, and maximum-plus-one |
| request/response bytes | exact maximum and one byte over; no partial result |
| identifier lengths | each identifier at maximum and one unit over; invalid grammar |
| stale catalog | below `MinCatalogRevision` waits or fails `STALE_STATE`; never weakens requirement |
| stale security | stale epoch/expired lease fails closed; re-delegation rule asserted |
| N/N-1 | N and N-1 client/server matrix plus unknown optional fields |
| capability mismatch | missing/wrong major fails and readiness is false |
| cross-org | forged payload/header cannot override delegation; repository not called |
| cross-AppInstallation | unauthorized workload/installation pair fails before record lookup |
| session/App state | revoked session, inactive user, disabled Connected App fail unauthenticated |
| internal mismatch | schema/value-kind mismatch is sanitized `INTERNAL_FAILURE` |

P1b supplied the core typed, null/absent, FLS, missing/RLS, forbidden,
cancellation, deterministic-order, and false/zero/empty cases. Later P2-P6
added generated-wire, deadline, process, compatibility, and trusted-delegation
evidence in their respective gates. That evidence still does not select a
production CRM consumer or replace the P7 request-bound metadata and V1
route-parity gates.

## 12. Consequences and next step

This contract keeps one source of truth and one read path: Runtime owns the
record, enforcement, and bound metadata/security view; L1 owns only its public
projection. It prevents a distributed 33-interface mirror and prevents CRM
lookup fan-out from becoming an RPC graph. The issue-tracker fixture continues
to prove App-neutral semantics without becoming a production App.

P1c-D, P2, the Runtime process walking slice, and P6 trusted-delegation/security
admission are complete. The minimal protobuf family remains isolated in the
separate generated wire module; the implementation did not remote the existing
33 in-process interfaces and did not begin production traffic cutover. C0's lack
of an exact selected-root consumer is not a reason to manufacture a route,
broaden the response, or compose access facts into this contract. Selected-root
remains available for a future exact consumer and continues to guard neutral
Runtime, wire, authorization, compatibility, and test-only non-CRM behavior.

The first production ownership slice is now the separate UI API record-access
use case selected by C0. It must receive its own use-case ADR, capability-specific
non-CRM conformance proof, generated client/server contract, serving-view gate,
and route parity/cutover evidence. None of those requirements reopens or mutates
the approved selected-root semantic boundary.
