# Approval Approver Resolution

Scope class: generic approval runtime substrate.

Approval routing is metadata-driven. The runtime reads authored approver facts
from `ProcessDefinition.Metadata` first, with legacy `ProcessNode` approver
fields as the fallback for older rows. It must not replace unresolved authored
metadata with the submitter, current actor, a profile literal, or any other
implicit fallback actor.

## Supported Approver Sources

- `user`: resolve the authored value as an exact `User.Id` first. If no User row
  exists for that Id, resolve it as `User.Username`. If the exact Id row exists
  but is inactive, soft-deleted, or missing an Id, the reference is unresolved
  and does not fall through to Username.
- `relatedUserField`: read the field named by the approver metadata from the
  target record. An empty field is unresolved.
- `queue`: resolve the authored value to a live `Group` with `Type = Queue`,
  verify `QueueSobject` supports the target object when the process object is
  known, then expand live user members through `_System_GroupMembershipClosure`.
- `role`: resolve the authored value to a live `UserRole`, then expand active
  users whose `User.UserRoleId` matches that role.
- `hierarchy`, `userHierarchyField`, and `previousApprover`: use the existing
  approval runtime context and hierarchy resolution rules.
- `adhoc`: use the authored user id value directly.

Queue and role expansion reads authorization-bearing actor sets through
`ApprovalService.queryAllPaged`. A partial actor set is not valid approval
routing input; the runtime must read to exhaustion or fail closed.

## Fail-Closed Contract

When authored approver metadata resolves to no active actor, submit and
advance/reject-back routing return a validation error on `assignedApprover`.
The diagnostic includes:

- authored approver type
- authored reference, when present
- approval step name, when known
- fail-closed reason: `no active approver resolved`

No `ProcessInstance`, `ProcessInstanceNode`, or `ProcessInstanceWorkitem` rows
are created for the failing transition. This keeps unresolved approver metadata
observable to the caller without creating zero-approver or self-routed approval
state.

## Boundary Rules

This policy is generic L0 approval substrate. It must not branch on tenant
objects, profile names, process developer names, record types, or customer
metadata values. New approver sources must define one metadata owner, one
runtime read path, fail-closed behavior, and tests for missing, deleted,
inactive, empty, and over-page actor sets before they can create work items.
