# Effective field permission projection

## Invariant and ownership

For the same admitted actor, metadata/security snapshot, field and operation,
the Runtime authorization decision and its effective-permission projection must
agree. L0 owns this interpretation under [the L0/L1 standard](l0-l1-standard.md);
L1 owns CRM presentation and the public API projection.

The neutral contract permits omission to mean unavailable. Sparse output is
therefore valid. The defect in #4816 is that L0 emitted aggregated stored grants
before applying missing-grant fallback, metadata restrictions and derived
policies. A missing stored grant is not necessarily a final denial. L1 was
entitled to interpret the missing effective decision as unavailable.

The create-default producer consequently generated an authorized OwnerId while
L1 had excluded that field. The later default-application check exposed this
contradiction as 503; field filtering already existed. Silently discarding the
default would leave the contradictory authority and missing fields intact.

## Current owners and cutover

- Persistence merges profile, direct and group grants. Its rows remain sparse
  authorization inputs. The permission request cache reads those inputs through
  `loadFieldPermissionInputs`; resolved rows must never feed fallback evaluation.
- `fieldAccessEvaluation` interprets Read, Create and Edit using those inputs and
  metadata. Point checks and the complete, single-object and selected multi-object
  projections use this evaluator. Projection indexes are request-local data, not
  another registry or authoring surface.
- `ContractPermissionAdmin` exports resolved field decisions. Runtime admission,
  Permission State transactions and the existing serving cache retain ownership
  of identity, snapshot binding, limits and invalidation. After authorizing a
  viewer to inspect another user, the complete and selected administrative reads
  create a child permission-input cache for that target. The viewer's cache
  stays intact; self reads keep reusing it. Request cancellation and admitted
  metadata/security context continue through the child scope. Cache identity
  mismatch remains fail-closed for accidental cross-subject reuse.
- The neutral field projection carries a distinct CanCreate decision. It
  includes object Create and field authorization; intrinsic field createability
  remains an admitted metadata fact. CanEdit retains the existing field-edit
  meaning and is combined with object Edit and intrinsic updateability by callers.
- L1 create/clone defaults, object-info, Describe, create layouts and creation
  actions use CanCreate. Read and update consumers retain their distinct gates.
  Object/record authorization still runs when the record is saved.

This implementation emits explicit resolved denials as well as allows. That is
an implementation choice, not a new requirement that every valid contract
response contain all fields. Consumers must continue treating omission as deny.
Credential read protection precedes administrator and stored-grant allowances.
Read protection does not itself prohibit a separately authorized write.

## Release compatibility

`runtime.permissions.read-effective.field-create.v1` is a host compatibility
feature, not another serving route. The CRM release consuming CanCreate requires
this feature at installation using the existing host compatibility mechanism.
Older L1 consumers can ignore the additive field; new consumers must not infer
creation access from CanEdit when an older producer omits it. Upgrade and rollback
must preserve the declared capability requirements, independently of source SHAs.

## Verification contract

1. Run owner tests for missing grants, explicit allow/deny/read-only grants,
   Create without Edit, Edit without Create, administrator and derived policies,
   and metadata-blocked reads. Compare point, cached and each bulk scope against
   independently stated expected decisions using real TiDB aggregation.
2. Exercise profile, direct and group assignment paths, bounded scope, cancellation,
   finite admission, metadata filtering and security-version invalidation. Use
   the Runtime ingress cache for target-user administrative reads, with both
   shared and different profiles; verify target fallback, viewer isolation,
   unauthorized-target rejection and self-read snapshot reuse.
3. Pass actual producer output through neutral wire mapping and L1 HTTP handlers;
   verify default values and field completeness, not only successful status.
4. Verify the real process path, including authorized and rejected saves, before
   deployment. Verify incompatible host/AppRelease combinations fail installation.
5. Recheck the original ordinary-user Credits journey and a harmless protected
   test field in the test2 browser, then remove disposable fixtures and grants.

The quick-action visibility string parser is a separate defect and is outside
this delivery. Verification results must distinguish local, process and browser
evidence; none is implied by this design document.

## Implementation verification, 2026-09-07

- Real TiDB: 39 cases across profile-owned, directly assigned and group-assigned
  permission sets passed at the point, cached, bulk and default-producer boundaries.
- Full Permissions, Records and Shared suites passed with a dedicated local TiDB.
  Full L1 AppService and semantic/wire suites passed. Runtime effective-permission,
  record-view and metadata projection tests passed, including the registered gRPC
  endpoint carrying different Create and Edit decisions.
- Target-subject regression: six ingress-cache cases failed before isolation and
  passed afterward. Complete, selected and field-only reads cover shared and
  different profiles; additional checks preserve viewer authorization and self
  snapshot reuse. The full Permissions suite passed in 29 seconds; scoped race
  checks passed in 91 seconds. An earlier full race run exceeded its three-minute
  aggregate bound in an unchanged large PermissionSet lifecycle test, which
  passed in the scoped rerun. No data race was reported.
- Contract owner gate passed, including immutable protocol baselines, deterministic
  regeneration, dependency boundaries, independent pinned-module tests and vet.
- The wider backend suite is **not green**: OAuth bootstrap panics in Controlplane,
  legacy CRM integration bootstrap rejects unsupported pack components/host
  requirements, and the FlowInterview fixture rejects its fake Flow reference.
  Each distinct failure was reproduced in an isolated worktree at unchanged Core
  `707b8a5b7914974bd5c8d2fa1f8144654b99a781`. The affected fixture files and
  bootstrap implementation are unchanged by this fix. The full automation
  integration package also reached its five-minute bound after those failures.

These results do not yet establish a complete deployment or browser acceptance.
