makePassableKit = (options = {}) => {
  const {
    encodeRemotable = (r, _) => Fail`remotable unexpected: ${r}`,
    encodePromise = (p, _) => Fail`promise unexpected: ${p}`,
    encodeError = (err, _) => Fail`error unexpected: ${err}`,
    format = 'legacyOrdered',

    decodeRemotable = (encoding, _) => Fail`remotable unexpected: ${encoding}`,
    decodePromise = (encoding, _) => Fail`promise unexpected: ${encoding}`,
    decodeError = (encoding, _) => Fail`error unexpected: ${encoding}`,
  } = options;

  /** @type {PassableKit['encodePassable']} */
  let encodePassable;
  const encodeOptions = { encodeRemotable, encodePromise, encodeError, format };
  if (format === 'compactOrdered') {
    const liberalDecode = makeInnerDecode(
      decodeCompactStringSuffix,
      decodeCompactArray,
      liberalDecoders,
    );
    /**
     * @param {string} encoding
     * @param {string} label
     * @returns {void}
     */
    const verifyEncoding = (encoding, label) => {
      !encoding.match(rC0) ||
        Fail`${b(
          label,
        )} encoding must not contain a C0 control character: ${encoding}`;
      const decoded = decodeCompactArray(`^v ${encoding} v `, liberalDecode);
      (isArray(decoded) &&
        decoded.length === 3 &&
        decoded[0] === null &&
        decoded[2] === null) ||
        Fail`${b(label)} encoding must be embeddable: ${encoding}`;
    };
    const encodeCompact = makeInnerEncode(
      encodeCompactStringSuffix,
      encodeCompactArray,
      { ...encodeOptions, verifyEncoding },
    );
    encodePassable = passable => `~${encodeCompact(passable)}`;
  } else if (format === 'legacyOrdered') {
    encodePassable = makeInnerEncode(
      encodeLegacyStringSuffix,
      encodeLegacyArray,
      encodeOptions,
    );
  } else {
    throw Fail`Unrecognized format: ${q(format)}`;
  }

  const decodeOptions = { decodeRemotable, decodePromise, decodeError };
  const decodeCompact = makeInnerDecode(
    decodeCompactStringSuffix,
    decodeCompactArray,
    decodeOptions,
  );
  const decodeLegacy = makeInnerDecode(
    decodeLegacyStringSuffix,
    decodeLegacyArray,
    decodeOptions,
  );
  const decodePassable = encoded => {
    // A leading "~" indicates the v2 encoding (with escaping in strings rather than arrays).
    // Skip it inside `decodeCompact` to avoid slow `substring` in XS.
    // https://github.com/endojs/endo/issues/1984
    if (encoded.charAt(0) === '~') {
      return decodeCompact(encoded, 1);
    }
    return decodeLegacy(encoded);
  };

  return harden({ encodePassable, decodePassable });
}
@param {EncodeOptions & DecodeOptions} [options]
@returns {PassableKit}