This looks much better! I have a few more nits though. They're mostly stylistic, but since this is a new core API, I'm going to be picky :)

0. We should document the return type: `@return {Promise.<{horizontal: Array.<number>, vertical: Array.<number>}>} - A promise that resolves with the sets of horizontal and vertical guide positions in the given document.`
1. I like that the method explicitly rejects without a proper documentId parameter, but I think it would actually be better to use the more relaxed check `if (documentId === undefined)`. This would allow document IDs to pass through which are stringified numbers. You might object that it's unhygienic to allow this, but I think it's actually very common to have document IDs as strings---as an example, iterating over a set of document keyed by ID will give you stringified IDs---and it seems needless to require callers to cast them to numbers right before we cast them back to strings.
2. We should avoid using deferred objects whenever possible, and it's easy to do so here. In the error branch, we can just return a [new rejected promise](https://github.com/kriskowal/q/wiki/API-Reference#qrejectreason): `return Q.reject("Document ID is required");` In the other branch, we should return a promise that is derived from applying the `then` method to the result of `evaluateJSXFile`:
```
return this.evaluateJSXFile("...").then(function (serializedGuides) {
  var guideParts = //...
  return {
    horizontal: //...
    vertical: ///
  };
})
```
This is better because a) we don't need the extra level of indirection provided by deferred objects; and b) if the call to `evaluateJSXFile` fails then that failure will propagate through to the promise that we return here. As written, if call to `evaluateJSXFile` fails then the deferred will never be resolved, and so neither will the returned promise. 

Those are my only complaints; I'm otherwise eager to push the merge button. Thanks again for contributing this!