Q:

¿Cuál es el valor primitivo de [] con base en ECMAScript 2016 (versión 7)?

Para escribir una respuesta a ¿Cómo funciona el condicional if (!+[]+!+[] == 2) en JavaScript? me aventuré a utilizar https://www.ecma-international.org/ecma-262/7.0/index.html para las referencias.
En ToPrimitive se explica el procedimiento para convertir una valor en un valor primitivo pero no he logrado asimilarlo para el caso de [].
Sé que [] es un objeto y que es equivalente a new Array()
También sé que un array es un objeto exótico, así que uno o más de sus métodos internos esenciales no tiene comportamiento predeterminado.

Notas:

Comentario de Paul Vargas (chat)
Revisar Array objects (sección de ECMAScript 2016)

Otras pregunta relacionadas:

¿Por qué _=$=+[],++_+''+$ es igual a 10?

A:

Respuesta corta
El valor primitivo de [] es '' (cadena de texto vacía).
Explicación
Finalmente me decidí a googlear y encontré esta respuesta a Why does ++[[]][+[]]+[+[]] return the string “10”?1, la cual es similar a mi respuesta a ¿Cómo funciona el condicional if (!+[]+!+[] == 2) en JavaScript? en cuando a que hace referencia a una especificación ECMASCript sólo que aquella no especifica a cual versión se refieren las citas, sin embargo, me ha sido útil para llenar el "hueco" que derivó en esta pregunta.
Mas abajo incluyo un par de extractos los cuales se pueden resumir como

document.write([].join() === '') // Resultado true

Extractos de la ECMAScript 2016 (versión 7)

12.2.5Array Initializer

NOTE
    An ArrayLiteral is an expression describing the initialization of an Array > object, using a list, of zero or more expressions each of which represents an array element, enclosed in square brackets. The elements need not be literals; they are evaluated each time the array initializer is evaluated.

Array elements may be elided at the beginning, middle or end of the element list. Whenever a comma in the element list is not preceded by an AssignmentExpression (i.e., a comma at the beginning or after another comma), the missing array element contributes to the length of the Array and increases the index of subsequent elements. Elided array elements are not defined. If an element is elided at the end of an array, that element does not contribute to the length of the Array.

7.1.1 ToPrimitive ( input [ , PreferredType ] )
The abstract operation ToPrimitive takes an input argument and an
  optional argument PreferredType. The abstract operation ToPrimitive
  converts its input argument to a non-Object type. If an object is
  capable of converting to more than one primitive type, it may use the
  optional hint PreferredType to favour that type. Conversion occurs
  according to Table 9:
Table 9: ToPrimitive Conversions

Input Type  Result
Undefined   Return input.
Null        Return input.
Boolean     Return input.
Number      Return input.
String      Return input.
Symbol      Return input.
Object      Perform the steps following this table.

When Type(input) is Object, the following steps are taken:

If PreferredType was not passed, let hint be "default".  
Else if PreferredType is hint String, let hint be "string".  
Else PreferredType is hint Number, let hint be "number".  
Let exoticToPrim be ? GetMethod(input, @@toPrimitive).  
If exoticToPrim is not undefined, then  
  
  
Let result be ? Call(exoticToPrim, input, « hint »).  
If Type(result) is not Object, return result.  
Throw a TypeError exception.  

If hint is "default", let hint be "number".  
Return ? OrdinaryToPrimitive(input, hint).  

When the abstract operation OrdinaryToPrimitive is called with
  arguments O and hint, the following steps are taken:  

Assert: Type(O) is Object.  
Assert: Type(hint) is String and its value is either "string" or "number".  
If hint is "string", then  
  
  
Let methodNames be « "toString", "valueOf" ».  

Else,  
  
  
Let methodNames be « "valueOf", "toString" ».  

For each name in methodNames in List order, do  
  
  
Let method be ? Get(O, name).  
If IsCallable(method) is true, then  
Let result be ? Call(method, O).  
If Type(result) is not Object, return result.  

Throw a TypeError exception.  

NOTE
When ToPrimitive is called with no hint, then it generally behaves as
  if the hint were Number. However, objects may over-ride this behaviour
  by defining a @@toPrimitive method. Of the objects defined in this
  specification only Date objects (see 20.3.4.45) and Symbol objects
  (see 19.4.3.4) over-ride the default ToPrimitive behaviour. Date
  objects treat no hint as if the hint were String.

En el caso de un objeto de tipo Array, el método para determinar el valor primitivo es join() de acuerdo a lo siguiente:

22.1.3.28 Array.prototype.toString ( )
When the toString method is called, the following steps are taken:

Let array be ? ToObject(this value).
Let func be ? Get(array, "join").
If IsCallable(func) is false, let func be the intrinsic function %ObjProto_toString%.
Return ? Call(func, array).

NOTE
The toString function is intentionally generic; it does not require
  that its this value be an Array object. Therefore it can be
  transferred to other kinds of objects for use as a method.

