An idea...

error = Crichton::TargetMethodResponseError 
if @target.respond_to?(source)
  unless (result = @target.send(source, super)).is_a?(Hash)
    raise error, "#{source} method on target must return Hash object"
  end

  predicates = {
    EXTERNAL: -> (opts) (opts[SOURCE] && opts[TARGET] && opts[PROMPT]),
    HASH: ->(opts) opts.is_a?(Hash)
    LIST: ->(opts) opts.is_a?(Array)
  }

  for result_type in [EXTERNAL, 
    if opts = result[result_type]
      raise error unless predicate[result_type](opts)
      return result
    end
  end
  raise error
else
 super
end