DefaultMaskingEngine
The default MaskingEngine: resolves each resource's policy once per call (via MaskingContext.memoize) and fails closed, entirely independent of any serialization library.
Fail-closed posture (see docs/adr/0001-serialization-context-passing.md and ADR 0006):
no principal on the call → the whole resource is masked (FailReason.NO_PRINCIPAL);
the resolver throws → the whole resource is masked (FailReason.RESOLVER_ERROR), unless resolverErrorMode is ResolverErrorMode.FAIL_REQUEST, which throws MaskingResolverException so the request fails instead of silently returning
{}(ADR 0011);a field's policy cannot satisfy the declared type → that field is dropped (FailReason.HIDE_NON_NULLABLE / FailReason.REDACT_UNSAFE).
Each fail-closed drop notifies onFailClosed; resource-level failures fire once per (call, resource) because MaskingContext.memoize runs resolution only once.