toThrowable = specimen => {
  harden(specimen);
  if (isErrorLike(specimen)) {
    return toPassableError(/** @type {Error} */ (specimen));
  }
  // Note that this step will fail if `specimen` would be a passable container
  // except that it contains non-passable errors that could be converted.
  // This will need to be fixed to do the TODO above.
  const passStyle = passStyleOf(specimen);
  if (isObject(specimen)) {
    switch (passStyle) {
      case 'copyArray': {
        const elements = /** @type {CopyArray} */ (specimen);
        for (const element of elements) {
          element === toThrowable(element) ||
            Fail`nested toThrowable coercion not yet supported ${element}`;
        }
        break;
      }
      case 'copyRecord': {
        const rec = /** @type {CopyRecord} */ (specimen);
        for (const val of values(rec)) {
          val === toThrowable(val) ||
            Fail`nested toThrowable coercion not yet supported ${val}`;
        }
        break;
      }
      case 'tagged': {
        const tg = /** @type {CopyTagged} */ (specimen);
        const { payload } = tg;
        payload === toThrowable(payload) ||
          Fail`nested toThrowable coercion not yet supported ${payload}`;
        break;
      }
      case 'error': {
        const er = /** @type {Error} */ (specimen);
        er === toThrowable(er) ||
          Fail`nested toThrowable coercion not yet supported ${er}`;
        break;
      }
      default: {
        throw Fail`A ${q(passStyle)} is not throwable: ${specimen}`;
      }
    }
  }
  return /** @type {Passable<never,never>} */ (specimen);
}
After hardening, if `specimen` is throwable, return it.
A specimen is throwable iff it is Passable and contains no PassableCaps,
i.e., no Remotables or Promises.
IOW, if it contains only copy-data and passable errors.

Otherwise, if `specimen` is *almost* throwable, for example, it is
an error that can be made throwable by `toPassableError`, then
return `specimen` converted to a throwable.

Otherwise, throw a diagnostic indicating a failure to coerce.

This is in support of the exo boundary throwing only throwables, to ease
security review.

TODO Adopt a more flexitble notion of throwable, in which
data containers containing non-passable errors can themselves be coerced
to throwable by coercing to a similar containers containing
the results of coercing those errors to passable errors.

@param {unknown} specimen
@returns {Passable<never, Error>}