 /// Once encoded, the system should use some underlying transport mechanism to send the
 /// bytes serialized by the invocation to the remote peer.
 ///
+/// ### Protocol requirements
+/// Similar to the ``DistributedActorSystem`` and its `remoteCall` and `remoteCallVoid` protocol requirements,
+/// the `DistributedTargetInvocationEncoder` contains a few methods which are not possible to express in source due to
+/// advanced use of generics combined with associated types. Specifically, the `recordArgument` and `recordReturnType`
+/// methods are not expressed in source as protocol requirements, but will be treated by the compiler as-if they were.
+///
+/// > Note: Although the `recordArgument` method is not expressed as protocol requirement in source,
+/// > the compiler will provide the same errors as-if it was declared explicitly in this protocol.
+///
+/// In addition to the compiler offering compile errors if those witnesses are missing in an adopting type,
+/// we present their signatures here for reference:
+///
+/// ```swift
+///  /// Record an argument of `Argument` type.
+///  /// This will be invoked for every argument of the target, in declaration order.
+/// mutating func recordArgument<Value: SerializationRequirement>(
+///     _ argument: DistributedTargetArgument<Value>
+/// ) throws
+///
+///  /// Ad-hoc requirement
+///  ///
+///  /// Record the return type of the distributed method.
+///  /// This method will not be invoked if the target is returning `Void`.
+///  mutating func recordReturnType<R: SerializationRequirement>(_ type: R.Type) throws
+/// ```
+///
 /// ## Decoding an invocation
 /// Since every actor system is going to deal with a concrete invocation type, they may
 /// implement decoding them whichever way is most optimal for the given system.

  // ==== ---------------------------------------------------------------------
  // - MARK: Resolving actors by identity

  /// Resolve a local or remote actor address to a real actor instance, or throw if unable to.
  /// The returned value is either a local actor or proxy to a remote actor.
  ///
  /// Resolving an actor is called when a specific distributed actors `init(from:)`
  /// decoding initializer is invoked. Once the actor's identity is deserialized
  /// using the `decodeIdentity(from:)` call, it is fed into this function, which
  /// is responsible for resolving the identity to a remote or local actor reference.
  ///
  /// If the resolve fails, meaning that it cannot locate a local actor managed for
  /// this identity, managed by this transport, nor can a remote actor reference
  /// be created for this identity on this transport, then this function must throw.
  ///
  /// If this function returns correctly, the returned actor reference is immediately
  /// usable. It may not necessarily imply the strict *existence* of a remote actor

  mutating func decodeReturnType() throws -> Any.Type?
}

/// Protocol a distributed invocation execution's result handler.
///
/// An instance conforming to this type must be passed when invoking
/// ``executeDistributedTarget(on:target:invocationDecoder:handler:)`` while handling an incoming distributed call.
///
/// The handler will then be invoked with the return value (or error) that the invoked target returned (or threw).
///
/// ### Protocol requirements
/// Similar to the ``DistributedActorSystem`` and its `remoteCall` and `remoteCallVoid` protocol requirements,
/// the `DistributedTargetInvocationResultHandler` contains a method which is not possible to express in source due to
/// advanced use of generics combined with associated types. Specifically, the `onReturn` method is not expressed in
/// source as protocol requirement, but will be treated by the compiler as-if they were.
///
/// > Note: Although the `onReturn` method is not expressed as protocol requirement in source,
/// > the compiler will provide the same errors as-if it was declared explicitly in this protocol.
///
/// In addition to the compiler offering compile errors if this witnesses is missing in an adopting type,
/// we present its signature here for reference:
///
/// ```swift
/// /// Ad-hoc protocol requirement
/// ///
/// /// Invoked when the distributed target execution returns successfully.
/// /// The `value` is the return value of the executed distributed invocation target.
/// func onReturn<Success: SerializationRequirement>(value: Success) async throws
/// ```
@available(SwiftStdlib 5.7, *)
public protocol DistributedTargetInvocationResultHandler {
  /// The serialization requirement that the value passed to `onReturn` is required to conform to.
  associatedtype SerializationRequirement

//  /// Ad-hoc protocol requirement
//  ///
//  /// Invoked when the distributed target execution returns successfully.
//  /// The `value` is the return value of the executed distributed invocation target.
//  func onReturn<Success: SerializationRequirement>(value: Success) async throws

  /// Invoked when the distributed target execution of a `Void` returning
  /// function has completed successfully.
  func onReturnVoid() async throws

  /// Invoked when the distributed target execution of a target has thrown an error.
  ///
  /// It is not guaranteed that the error conform to the ``SerializationRequirement``;
  /// This guarantee is only given to return values (and offered by `onReturn`).
  func onThrow<Err: Error>(error: Err) async throws
}

